验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上用验证码是现在很多网站通行的方式,我们利用比较简易的方式实现了这个功能。
这个问题可以由计算机生成并评判,但是必须只有人类才能解答。由于计算机无法解答CAPTCHA的问题,所以回答出问题的用户就可以被认为是人类。
Php制作动态验证码是基于php的图像处理,下面首先介绍一下php的图像处理。
一.php图像处理简介在PHP5中,动态图象的处理要比以前容易得多。PHP5在php.ini文件中包含了GD扩展包,只需去掉GD扩展包的相应注释就可以正常使用了。PHP5包含的GD库正是升级的GD2库,其中包含支持真彩图像处理的一些有用的JPG功能。
一般生成的图形,通过PHP的文档格式存放,但可以通过HTML的图片插入方式SRC来直接获取动态图形。比如,验证码、水印、微缩图等。
创建图像的一般流程:
第一步,设置文件MIME类型,输出类型 将输出类型改成图像流1).设定标头,告诉浏览器你要生成的MIME类型。
2).创建一个图像区域,以后的操作都将基于此图像区域。
3).在空白图像区域绘制填充背景。
4).在背景上绘制图形轮廓输入文本。
5).输出最终图形。
6).清除所有资源。
7).其他页面调用图像。
header('Content-Type: image/png;');
一般生成的图像可以是png,jpeg,gif,wbmp
第二步,创建一个图形区域,图像背景imagecreatetruecolor() 返回一个图像标识符,代表了一幅大小为 x_size
和 y_size
的黑色图像。语法:resource imagecreatetruecolor ( int $width
, int $height
)
$im = imagecreatetruecolor(200,200);
第三步,在空白图像区域绘制填充背景
要有颜色填充器;imagecolorallocate -- 为一幅图像分配颜色;语法:int imagecolorallocate ( resource $image
, int $red
, int $green
, int $blue
)
$blue = imagecolorallocate($im,0,102,255);
将这个blue颜色填充到背景上去;imagefill -- 区域填充;语法:bool imagefill ( resource $image
, int $x
, int $y
, int $color
)
第四步,在蓝色的背景上输入一些线条,文字等imagefill($im,0,0,$blue);
颜色填充器
$white = imagecolorallocate($im,255,255,255);
画两条线段:imageline
imageline() 用 color
颜色在图像 image
中从坐标 x1
,y1
到 x2
,y2
(图像左上角为 0, 0)画一条线段。语法:bool imageline ( resource $image
, int $x1
, int $y1
, int $x2
, int $y2
, int $color
)
imageline($im,0,0,200,200,$white);
imageline($im,200,0,0,200,$white);
水平地画一行字符串:imagestring
imagestring() 用 col
颜色将字符串 s
画到 image
所代表的图像的 x
,y
坐标处(这是字符串左上角坐标,整幅图像的左上角为 0,0)。如果font
是 1,2,3,4 或 5,则使用内置字体。语法:bool imagestring ( resource $image
, int $font
, int $x
, int $y
, string $s
, int $col
)
第五步,输出最终图形imagestring($im,5,66,20,'jingwhale',$white);
imagepng() 将 GD 图像流(image
)以 PNG 格式输出到标准输出(通常为浏览器),或者如果用 filename
给出了文件名则将其输出到该文件。语法:bool imagepng ( resource $image
[, string $filename
] )
第六步,我要将所有的资源全部清空imagepng($im);
imagedestroy() 释放与 image
关联的内存。语法:bool imagedestroy ( resource $image
)
其他页面(html)调用创建的图形imagedestroy($im);
<img src="Demo4.php" alt="PHP创建的图片" />
示例代码如下:
<?php //第一步,设置文件MIME类型 header('Content-Type: image/png;'); //第二步,创建一个图形区域,图像背景 $im = imagecreatetruecolor(200,200); //第三步,在空白图像区域绘制填充背景 $blue = imagecolorallocate($im,0,102,255); imagefill($im,0,0,$blue); //第四步,在蓝色的背景上输入一些线条,文字等 $white = imagecolorallocate($im,255,255,255); imageline($im,0,0,200,200,$white); imageline($im,200,0,0,200,$white); imagestring($im,5,66,20,'Jing.Whale',$white); //第五步,输出最终图形 imagepng($im); //第六步,我要将所有的资源全部清空 imagedestroy($im); ?>
显示效果:
二.创建动态验证码附:代码源地址https://github.com/cnblogs-/php-captcha
1. 创建带验证码的图片,并模糊背景随机码采用16进制;模糊背景即在图片背景加上线条、雪花等。
1)创建随机码
for ($i=0;$i<$_rnd_code;$i++) { $_nmsg .= dechex(mt_rand(0,15)); }
string dechex ( int $number
),返回一字符串,包含有给定 number
参数的十六进制表示。
2)保存在session
$_SESSION['code'] = $_nms
3)创建图片
//创建一张图像$_img = imagecreatetruecolor($_width,$_height);//白色$_white = imagecolorallocate($_img,255,255,255);//填充imagefill($_img,0,0,$_white);if ($_flag) {//黑色,边框 $_black = imagecolorallocate($_img,0,0,0); imagerectangle($_img,0,0,$_width-1,$_height-1,$_black);}
4)模糊背景
//随机画出6个线条for ($i=0;$i<6;$i++) { $_rnd_color = imagecolorallocate($_img,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255)); imageline($_img,mt_rand(0,$_width),mt_rand(0,$_height),mt_rand(0,$_width),mt_rand(0,$_height),$_rnd_color); }//随机雪花for ($i=0;$i<100;$i++) { $_rnd_color = imagecolorallocate($_img,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255)); imagestring($_img,1,mt_rand(1,$_width),mt_rand(1,$_height),'*',$_rnd_color); }
5)输出及销毁
//输出验证码for ($i=0;$i<strlen($_SESSION['code']);$i++) { $_rnd_color = imagecolorallocate($_img,mt_rand(0,100),mt_rand(0,150),mt_rand(0,200)); imagestring($_img,5,$i*$_width/$_rnd_code+mt_rand(1,10),mt_rand(1,$_height/2),$_SESSION['code'][$i],$_rnd_color); }//输出图像header('Content-Type: image/png');imagepng($_img);//销毁imagedestroy($_img);
将其封装在global.func.php全局函数库中,函数名为_code(),以便调用。我们将设置$_width ,$_height ,$_rnd_code,$_flag 四个参数,以增强函数的灵活性。
* @param int $_width 验证码的长度:如果要6位长度推荐75+50;如果要8位,推荐75+50+50,依次类推* @param int $_height 验证码的高度* @param int $_rnd_code 验证码的位数* @param bool $_flag 验证码是否需要边框:true有边框, false无边框(默认)
封装后的代码如下:
<?php /** * [verification-code] (C)2015-2100 jingwhale. * * This is a freeware * $Id: global.func.php 2015-02-05 20:53:56 jingwhale$ */
/** * _code()是验证码函数 * @access public * @param int $_width 验证码的长度:如果要6位长度推荐75+50;如果要8位,推荐75+50+50,依次类推 * @param int $_height 验证码的高度 * @param int $_rnd_code 验证码的位数 * @param bool $_flag 验证码是否需要边框:true有边框, false无边框(默认) * @return void 这个函数执行后产生一个验证码 */function _code($_width = 75,$_height = 25,$_rnd_code = 4,$_flag = false) { //创建随机码 for ($i=0;$i<$_rnd_code;$i++) { $_nmsg .= dechex(mt_rand(0,15)); } //保存在session $_SESSION['code'] = $_nmsg; //创建一张图像 $_img = imagecreatetruecolor($_width,$_height); //白色 $_white = imagecolorallocate($_img,255,255,255); //填充 imagefill($_img,0,0,$_white); if ($_flag) { //黑色,边框 $_black = imagecolorallocate($_img,0,0,0); imagerectangle($_img,0,0,$_width-1,$_height-1,$_black); } //随即画出6个线条 for ($i=0;$i<6;$i++) { $_rnd_color = imagecolorallocate($_img,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255)); imageline($_img,mt_rand(0,$_width),mt_rand(0,$_height),mt_rand(0,$_width),mt_rand(0,$_height),$_rnd_color); } //随即雪花 for ($i=0;$i<100;$i++) { $_rnd_color = imagecolorallocate($_img,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255)); imagestring($_img,1,mt_rand(1,$_width),mt_rand(1,$_height),'*',$_rnd_color); } //输出验证码 for ($i=0;$i<strlen($_SESSION['code']);$i++) { $_rnd_color = imagecolorallocate($_img,mt_rand(0,100),mt_rand(0,150),mt_rand(0,200)); imagestring($_img,5,$i*$_width/$_rnd_code+mt_rand(1,10),mt_rand(1,$_height/2),$_SESSION['