+ -
当前位置:首页 → 问答吧 → 轻松学php图片验证码

轻松学php图片验证码

时间:2006-12-22

来源:互联网

最近要做学校的项目,为了安全要用到图片验证技术,所以就找了找文章,
肯了些时间,把自己的心得写出来,也算是说下自己的理解吧,
用理解错误的地方请指正,我也是菜菜,
我拿一篇写的不错的文章来分析,或者按照自己的思路来看他的代码.

php图片验证技术关键的是用个函数
imagestring()这个函数,老样子看下函数原型,对理解会有好大的帮助
//int imagestring(resource image,int font,int x,int y,string s, int col);
看下手册会有好多帮助
imagestring() 用 col 颜色将字符串 s 画到 image 所代表的图像的 x,y 座标处(图像的左上角为 0, 0)。如果 font 是 1,2,3,4 或 5,则使用内置字体。
这里主要有三个关键参数
resource image,string s ,int col
1,
下面来看看
resource image ,int col
这二个一起分析,为啥,慢慢来看
这个image是划好的图
要划图,要遵循几步
1.1
第一是创建图像文件流
imagecreate()当然用imagecreateturecolor()也可以,
这里用imagecreate来例子,
老方法看函数原型和手册的解释
resource imagecreate ( int x_size, int y_size)
imagecreate() 返回一个图像标识符,代表了一幅大小为 x_size 和 y_size 的空白图像。
那么咱们就可以使用它来创建一个空白图像.
$im=imagecreate(90,30);
1.2
因为是空白的,所以要找给它填充的颜色
用到这个函数
imagecolorallocate()
看原型和手册
int imagecolorallocate ( resource image, int red, int green, int blue)
imagecolorallocate() 返回一个标识符,代表了由给定的 RGB 成分组成的颜色。image 参数是 imagecreate() 函数的返回值。red,green 和 blue 分别是所需要的颜色的红,绿,蓝成分。这些参数是 0 到 255 的整数或者十六进制的 0x00 到 0xFF。imagecolorallocate() 必须被调用以创建每一种用在 image 所代表的图像中的颜色。
看下最后一句,imagecolorallocate() 必须被调用以创建每一种用在 image 所代表的图像中的颜色,那么咱们来建立几种颜色,来方便以后的填充,同时这个颜色也是
这里主要有三个关键参数
resource image,string s ,int col
int col 的颜色设置
我们来方便设置三个颜色吧
$red=imagecolorallocate($im,255,0,0);
$white = ImageColorAllocate($im, 255,255,255);
$gray = ImageColorAllocate($im, 200,200,200);
这三个不用解释了吧,就是r g b 配合出来的颜色.
1.3,
既然空白图像和填充颜色已经出来了,那我们来填充吧
用到这个函数
imagefill()
int imagefill ( resource image, int x, int y, int color)
imagefill() 在 image 图像的坐标 x,y(图像左上角为 0, 0)处用 color 颜色执行区域填充(即与 x, y 点颜色相同且相邻的点都会被填充)。
imagefill($im,0,0,$white);//用白色填充是为了让干扰素更好的起作用
那这样我的三个参数中其中二个参数已经解决了,resource image,int col
我们来看第二个参数string s;

2
第二个参数string s
2,1
因为是验证码,防止恶意攻击,那么一定要设置成随机出来的那样才不会出问题,
srand((double)microtime()*1000000);//播下一个生成随机数字的种子,以方便下面随机数生成的使用,
生成数字和字母混合的验证码
$ychar="0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
$list=explode(",",$ychar);//explode函数比较简单,就是提前每个间隔,的字符并把他们组成数组,不理解的看下手册吧,很容易理解的
已经产生了一个包含这36个字符的数组,剩下的就是让他们产生随机的四位数了
for($i=0;$i<4;$i++){
  $randnum=rand(0,35);
  $authnum.=$list[$randnum]." ";//ed 加入一个空格
}
这个循环,循环的次数是四次,我还是在解释下吧,其实很简单,
假设第一次循环,rand(0,35)意思是随机出现0到35之间的数组
假设是第0个,那么就是1 $authnum=1."";
第二次循环
如果$randum=12,那么$authnum=1.$list[$randnum]."";
也就是$authnum=1 C;
如此循环到第四位,
那么就这样产生了随机的四位数,

既然三个参数我们都解决了,那么就可以用
imagestring()函数来创建图片了,
imagestring($im, 5, 10, 3, $authnum, $red);
创建了以后,我们要输出图片
imagepng($im);
imagedestroy($im);
同时我们要在文件头说明,要输出的文件的类型
Header("Content-type: image/PNG");

3
其实功能是实现了,但是为了更好的安全,我们要加入干扰素,
啥是干扰素就是干扰的因素呗,哈
用到这个函数
int imagesetpixel ( resource image, int x, int y, int color)
imagesetpixel() 在 image 图像中用 color 颜色在 x, y 坐标(图像左上角为 0, 0)上画一个点。
看他的解释,在画一个点,所以咱们肯定要用个循环了,
就是多画几个点,哈
for($i=0;$i<400;$i++){ //加入干扰象素
$randcolor = ImageColorallocate($im,rand(0,255),rand(0,255),rand(0,255));
imagesetpixel($im, rand()%90 , rand()%30 , $gray);
}
for循环的第一个,产生随机的颜色,当然也可以使用咱们上面定义的
这里用的就是上面定义的$gray,那个400是产生的像素点的个数
没啥要解释的了吧

顺便把我看的那个好的文章帖下来,
复制内容到剪贴板
代码:
<?php
//FileName:authimg.php
//Description:
//Creater:alvar
//Createtime:2006-5-4
//Lastmodtime:
session_start();
?>
<?php
//生成验证码图片
Header("Content-type: image/PNG");
srand((double)microtime()*1000000);//播下一个生成随机数字的种子,以方便下面随机数生成的使用
//session_start();//将随机数存入session中
$_SESSION['authnum']="";
$im = imagecreate(90,20) or die("Cant's initialize new GD image stream!");  //制定图片背景大小
$red = ImageColorAllocate($im, 255,0,0); //设定三种颜色
$white = ImageColorAllocate($im, 255,255,255);
$gray = ImageColorAllocate($im, 200,200,200);
//imagefill($im,0,0,$gray); //采用区域填充法,设定(0,0)
imagefill($im,0,0,$white);//ed
//生成数字和字母混合的验证码方法
$ychar="0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
$list=explode(",",$ychar);
for($i=0;$i<4;$i++){
  $randnum=rand(0,35);
  $authnum.=$list[$randnum]." ";//ed 加入一个空格
}
//while(($authnum=rand()%100000)<10000); //生成随机的四位数
//将四位整数验证码绘入图片
$_SESSION['authnum']=$authnum;
//int imagestring(resource image,int font,int x,int y,string s, int col)
imagestring($im, 5, 10, 3, $authnum, $red);
//用col颜色将字符串s画到image所代表的图像的x,y座标处(图像的左上角为0,0)。
//如果 font 是 1,2,3,4 或 5,则使用内置字体

for($i=0;$i<400;$i++){ //加入干扰象素 {
$randcolor = ImageColorallocate($im,rand(0,255),rand(0,255),rand(0,255));
// imagesetpixel($im, rand()%90 , rand()%30 , $randcolor);
imagesetpixel($im, rand()%90 , rand()%30 , $gray);
}
ImagePNG($im);
ImageDestroy($im);
?>
最后看下效果图

[ 本帖最后由 baker95935 于 2006-12-28 01:40 编辑 ]

作者: baker95935   发布时间: 2006-12-21

欢迎高手指正,本人菜菜,

作者: baker95935   发布时间: 2006-12-21

最好去掉零和欧,1和I,2和Z,5和S等看起来容易弄混的字母。

作者: zig   发布时间: 2006-12-22

写得不错

作者: xiaojia   发布时间: 2006-12-22


我比你菜多了
:')
没有可比性
谢谢你我有学了好多东东

作者: wang350   发布时间: 2007-01-08

不错,我也来个
复制PHP内容到剪贴板
PHP代码:

<?
//生成新的四位整数验证码
session_start();//开始会话
$authnum = ''; 
$str = 'abcdefghijkmnpqrstuvwxyz1234567890'; 
$l = strlen($str); 
for($i=1;$i<=4;$i++)

$num=rand(0,$l); 
$authnum.= $str[$num]; 
}
//生成SESSION变量
$_SESSION['code']=$authnum;
//生成验证码图片
Header("Content-type: image/PNG");
srand((double)microtime()*1000000);
$im = imagecreate(50,20);
$black = ImageColorAllocate($im, 0,0,0);
$white = ImageColorAllocate($im, 255,255,255);
$gray = ImageColorAllocate($im, 200,200,200);
imagefill($im,68,30,$gray);
//将四位整数验证码绘入图片
imagestring($im, 5, 6, 3, $authnum, $white);
for($i=0;$i<90;$i++) //加入干扰象素
{
imagesetpixel($im, rand()%70 , rand()%30 , $gray);
}
ImagePNG($im);
ImageDestroy($im);
?>

作者: leehui1983   发布时间: 2007-01-08

收藏,哈哈,今天来学习了不少东西

作者: gd286115   发布时间: 2007-02-21

我想加个PHP的群.谁有啊

作者: gd286115   发布时间: 2007-02-22

8977512
我是群主
嘎嘎!:D

作者: niohe   发布时间: 2007-02-22

先顶完再看```````````````````````

作者: dmkf   发布时间: 2007-02-22

加了。希望能多学到相关的知识。嘎嘎~

我今天买了本传说中的“圣经”

大家谁看过这本书。这本书好象声望不错哦

作者: gd286115   发布时间: 2007-02-22

我看过,不过还没看完
也不想看了
呵呵
这书不错!

作者: niohe   发布时间: 2007-02-23

验证码的目的主要是
防止用户频繁的(手动或自动)进行某些操作,从而给系统或者db带来巨大的负担。
所以我个人的看法是:识别码以人眼分辨容易,使用程序自动分辨为最好。
象QQ网站上用的那种上下错位左右扭曲加条带形状干扰码的中文形式验证码图片。。。咳。。。极品。。。
楼上两位的代码都很漂亮,不过相对来说,写程序做自动识别可能比较容易。
所以,我的意见是:
1。验证码以中文为最佳;【识别困难】
2。如果用数字字母组合,尽量最随机的上下左右错位和变形;【识别困难】
3。文字色和扰码色接近为好(不过会苦了色盲用户吧。。。)【否则容易被轻易的把扰码过滤】,文字颜色本身最好也是混色=。=

作者: akuma   发布时间: 2007-02-26

:)

作者: luzhou   发布时间: 2007-02-28

应该加精

作者: 淘园君   发布时间: 2007-02-28

嗯 6楼方法也是我用的

作者: boobycn   发布时间: 2007-03-03

很详细,不错!:)

作者: iteasynow   发布时间: 2007-03-04

引用:
原帖由 leehui1983 于 2007-1-8 11:31 发表
不错,我也来个

<?
//生成新的四位整数验证码
session_start();//开始会话
$authnum = '';
$str = 'abcdefghijkmnpqrstuvwxyz1234567890';
$l = strlen($str);
for($i=1;$i<=4;$i++)
{
$n ...
辉老大,用你的代码生成的验证码,有时候最后一位字符看不到,和背景融合在一起了

作者: Tiny   发布时间: 2007-03-06

引用:
原帖由 akuma 于 2007-2-26 21:57 发表
验证码的目的主要是
防止用户频繁的(手动或自动)进行某些操作,从而给系统或者db带来巨大的负担。
所以我个人的看法是:识别码以人眼分辨容易,使用程序自动分辨为最好。
象QQ网站上用的那种上下错位左右 ...
我想知道如何自动识别   就是没有任何干扰,且由简单的字母数字组合
根本不懂破解原理

作者: silasoni   发布时间: 2007-03-14

引用:
原帖由 dmkf 于 2007-2-22 14:31 发表
先顶完再看```````````````````````

作者: remote_addr   发布时间: 2007-03-20

:)

作者: 活着信仰着   发布时间: 2007-03-21

解释得很好 谢谢了

作者: flymouse   发布时间: 2007-03-27

:)

作者: 特蓝克斯   发布时间: 2007-03-28

呵呵,支持一下哦

作者: 默默   发布时间: 2007-04-01

先支持一下先 学习啊

作者: 纯色理想   发布时间: 2007-04-03

不错。。顶你一个~

作者: wsp8   发布时间: 2007-04-03

非常�x�x您的分享
好看喔~~
Ec2Link Leader of Website Hosting

作者: BeeGirl033   发布时间: 2007-04-05

谢谢分享,:)

作者: cjccjc2000   发布时间: 2007-05-08

thanks

作者: xlight   发布时间: 2007-05-08

恩 都不错 支持一下哦

作者: welefen   发布时间: 2007-05-08

学习楼,不错啊~

作者: fly1983   发布时间: 2007-05-15

顶完再看!

作者: xiaoqiang527   发布时间: 2007-05-16

加了�仔��|�|
可以自行�O定要出�F����字,��人�X得6位�当容^�m��.

<?php
//FileName:authimg.php
//Description:
//Creater:alvar
//Createtime:2006-5-4
//Lastmodtime:
session_start();
?>
<?php
//生成���C�a�D片
Header("Content-type: image/PNG");
srand((double)microtime()*1000000);//播下一��生成�S�C�底值姆N子,以方便下面�S�C�瞪�成的使用
//session_start();//�㈦S�C�荡嫒�session中
$_SESSION['authnum']="";
$imwid = '120';  //��
$imhei = '20';   //高
$num = '6'; //�O定�孜���
$im = imagecreate($imwid,$imhei) or die("Cant's initialize new GD image stream!");  //制定�D片背景大小
$red = ImageColorAllocate($im, 255,0,0); //�O定三�N��色
$white = ImageColorAllocate($im, 255,255,255);
$gray = ImageColorAllocate($im, 200,200,200);
//imagefill($im,0,0,$gray); //�裼��^域填充法,�O定(0,0)
imagefill($im,0,0,$white);//ed
//生成�底趾妥帜富旌系尿��C�a方法
$ychar="0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
$list=explode(",",$ychar);
for($i=0;$i<$num;$i++){
  $randnum=rand(0,35);
  $authnum.=$list[$randnum]." ";//ed 加入一��空格
}
//while(($authnum=rand()%100000)<10000); //生成�S�C的四位��
//�⑺奈徽��凋��C�a�L入�D片
$_SESSION['authnum']=$authnum;
//int imagestring(resource image,int font,int x,int y,string s, int col)
imagestring($im, 5, 10, 3, $authnum, $red);
//用col��色�⒆址�串s��到image所代表的�D像的x,y座�颂�(�D像的左上角��0,0)。
//如果 font 是 1,2,3,4 或 5,�t使用�戎米煮w

for($i=0;$i<400;$i++){ //加入干�_象素 {
$randcolor = ImageColorallocate($im,rand(0,255),rand(0,255),rand(0,255));
// imagesetpixel($im, rand()%90 , rand()%30 , $randcolor);
imagesetpixel($im, rand()%$imwid , rand()%($imhei+10) , $gray);
}
ImagePNG($im);
ImageDestroy($im);
?>

作者: junesnow17   发布时间: 2007-05-22

留下个记号

作者: 阳光小老鼠   发布时间: 2008-03-25

无级PHP技术群
正在发展壮大中,热烈欢迎PHPer加入!!!

作者: 开心小孩   发布时间: 2008-03-26

好贴

作者: chaguifei   发布时间: 2008-03-26

不错

作者: 清竹�w翔   发布时间: 2008-03-27

做一个记号  呵呵

作者: imagic   发布时间: 2008-03-30

收藏了

作者: 一条尸体   发布时间: 2008-03-30