谈谈那些年 PHP 中非常牛的验证码

发布于 2019-11-12 19:27:45 字数 3825 浏览 1416 评论 0

验证码已经是现在网站中非常基础的知识点了,验证码的存在可以防止恶意破解密码、刷票、灌水,可以有效的防止暴力破解特定用户,现在就来了解谈谈那些年PHP中非常牛的验证码。

首先以四位验证码为例(多位验证码一样的道理)。

目前网站大多仍然采用静态图片验证码,因为这样实现起来简单又方便,不需要过硬的功底,当然这也是基础。而其原理也就是通过 PHP 的画图功能将文字画成图片返回到页面。因此我们解决的问题也就只有三步而已:

  1. 随机生成验证码的内容
  2. 将验证码转换成图片,即绘图
  3. 将所绘出的图返回到页面中

当然PHP默认是没有开启绘图功能的,因此在 php.ini 的配置文件中先开启绘图功能,打开 php.ini 文件搜索到:

;extension=php_gd2.dl

将前面的分号去掉即可,保存文件然后重启 Apache 或者 IIS。

那根据第一点,大家首先应该会想到数字的验证码,因为这容易,随机生成个几个数字,然后拼起来也就行了,PHP 大概的实现代码如下:

$validateCode = '';
for ($i = 0; $i < 4; $i ++) {
  $validateCode .= (0, 9);
}
echo $validateCode;

然后仔细想想,现在的网站验证码都有字母,可这玩意儿都没字母,然后又想到,直接把上面那玩意儿搞成十六进制就好了。

$validateCode = '';
for ($i = 0; $i < 4; $i ++) {
  $validateCode .= ((0, 16));
}  
echo $validateCode;

好像有点自作聪明的赶脚呀,不过想想,也算是有几个字母了,可却只有 a,b,c,d,e,f,那要是需要所有字母咋办呢?

再想想也就想到把所有的字母和数字等在一个字符串中列出来,然后通过随机下标的形式去随机获取对应的值,也就成了这样:

$validateCode = '';
$str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890';
for ($i = 0; $i < 4; $i ++) {
  $validateCode .= $str[(0, ($str))];
}
echo $validateCode;

终于像验证码里的随机数了,不过看到下面的方法,有总瞬间被秒的赶脚:

$str = 'ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789';
$validateCode = substr(str_shuffle($str), 0, 4);

str_shuffle 方法将字符串内容打乱,substr($str, 0, 4) 取到了前四个数。这样是完全没有问题的!不过细心的看的出来,这样的验证码里的内容是不会重复的。

以上验证码也就产生了,接下来也就要将验证码用 PHP 画出来了。

$str = 'ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789';
$validateCode = substr(str_shuffle($str), 0, 4);

// 创建一张宽为64px,高为32px的图片
$img = imagecreatetruecolor(64, 32);
// 将图片的背景颜色设置成黑色,颜色值分别对应RGB
$bgcolor = imagecolorallocate($img, 0, 0, 0);

// 创建白色
$white = imagecolorallocate($img, 255, 255, 255);

/* 添加文字在图片中,
第二个参数为文字的大小,只能在1~5
第三个参数为x坐标
第4个参数为y坐标
第5个参数为文字的内容
第6个参数为文字的颜色*/
imagestring($img, 6, 16, 6, $validateCode, $white);

// 返回成图片
header('Content-type: image/png');
imagepng($img);

当然,这样的话验证码就太好识别了,就只是单纯的黑底白字,为了增加点难度,我们就多加几条线叠加在验证码的上面。

$str = 'ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789';
$validateCode = substr(str_shuffle($str), 0, 4);

// 创建一张宽为64px,高为32px的图片
$img = imagecreatetruecolor(64, 32);
// 将图片的背景颜色设置成黑色,颜色值分别对应RGB
$bgcolor = imagecolorallocate($img, 0, 0, 0);

// 创建白色
$white = imagecolorallocate($img, 255, 255, 255);

for ($i = 0; $i < 30; $i ++) { 
  /* 在图片上画线
  其中第2个参数表示线的x起始坐标
  第3个参数表示线的y起始坐标
  第4个参数表示x的终止坐标
  第5个参数表示y的终止坐标
  第6个参数表示颜色
  此处生成一个随机颜色 */
  $res = imagecolorallocate($img, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
  imageline($img, mt_rand(0, 110), mt_rand(0, 25), mt_rand(0, 110), mt_rand(0, 25), $res);
}

/* 添加文字在图片中,
第二个参数为文字的大小,只能在1~5
第三个参数为x坐标
第4个参数为y坐标
第5个参数为文字的内容
第6个参数为文字的颜色*/
imagestring($img, 6, 16, 6, $validateCode, $white);

// 返回成图片
header('Content-type: image/png');
imagepng($img);

结果也就成了这样,当然要想实现验证码,这样还是不够滴,需要通过将验证码生成的随机数存到服务器的 Session 中,$_SESSION['validate'] = $validateCode; 然后在通过客户端输入的验证码与之对比即可。

PHP 中的验证码也就这样实现了,当然前面也说过了,这是最基础的代码,可以通过你的想法将其改变为实现算术的验证码,中文的验证码,或其它一些有趣的验证码,以减少其枯燥性又实现安全性。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84961 人气
更多

推荐作者

已经忘了多久

文章 0 评论 0

15867725375

文章 0 评论 0

LonelySnow

文章 0 评论 0

走过海棠暮

文章 0 评论 0

轻许诺言

文章 0 评论 0

信馬由缰

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文