php生成动态验证码 加减算法验证码 简单验证码
程序员文章站
2023-11-22 14:59:34
预览效果: 加减验证: yi 简单验证码: 1.验证码为全自动区分计算机和人类的图灵测试的缩写。是一种区分用户是计算机和人的公共全自动程序。2.验证码主要应用场景:登录、注册确定前,发布、回复信息前,疑似机器请求时,做人/机器校验。3.实现步骤:(1)生成底图; 依赖php图片处理库GD,http: ......
预览效果:
<?php /** *imagecode 生成包含验证码的gif图片的函数 *@param $string 字符串 *@param $width 宽度 *@param $height 高度 **/ function imagecode($string='',$width=75,$height=25){ $authstr=$string?$string:((time()%2==0)?mt_rand(1000,9999):mt_rand(10000,99999)); $board_width=$width; $board_height=$height; // 生成一个32帧的gif动画 for($i=0;$i<32;$i++){ ob_start(); $image=imagecreate($board_width,$board_height); imagecolorallocate($image,0,0,0); // 设定文字颜色数组 $colorlist[]=imagecolorallocate($image,15,73,210); $colorlist[]=imagecolorallocate($image,0,64,0); $colorlist[]=imagecolorallocate($image,0,0,64); $colorlist[]=imagecolorallocate($image,0,128,128); $colorlist[]=imagecolorallocate($image,27,52,47); $colorlist[]=imagecolorallocate($image,51,0,102); $colorlist[]=imagecolorallocate($image,0,0,145); $colorlist[]=imagecolorallocate($image,0,0,113); $colorlist[]=imagecolorallocate($image,0,51,51); $colorlist[]=imagecolorallocate($image,158,180,35); $colorlist[]=imagecolorallocate($image,59,59,59); $colorlist[]=imagecolorallocate($image,0,0,0); $colorlist[]=imagecolorallocate($image,1,128,180); $colorlist[]=imagecolorallocate($image,0,153,51); $colorlist[]=imagecolorallocate($image,60,131,1); $colorlist[]=imagecolorallocate($image,0,0,0); $fontcolor=imagecolorallocate($image,0,0,0); $gray=imagecolorallocate($image,245,245,245); $color=imagecolorallocate($image,255,255,255); $color2=imagecolorallocate($image,255,0,0); imagefill($image,0,0,$gray); $space=15;// 字符间距 if($i>0){// 屏蔽第一帧 $top=0; for($k=0;$k<strlen($authstr);$k++){ $colorrandom=mt_rand(0,sizeof($colorlist)-1); $float_top=rand(0,4); $float_left=rand(0,3); imagestring($image,6,$space*$k,$top+$float_top,substr($authstr,$k,1),$colorlist[$colorrandom]); } } for($k=0;$k<20;$k++){ $colorrandom=mt_rand(0,sizeof($colorlist)-1); imagesetpixel($image,rand()%70,rand()%15,$colorlist[$colorrandom]); } // 添加干扰线 for($k=0;$k<3;$k++){ $colorrandom=mt_rand(0,sizeof($colorlist)-1); $todrawline=1; if($todrawline){ imageline($image,mt_rand(0,$board_width),mt_rand(0,$board_height),mt_rand(0,$board_width),mt_rand(0,$board_height),$colorlist[$colorrandom]); }else{ $w=mt_rand(0,$board_width); $h=mt_rand(0,$board_width); imagearc($image,$board_width-floor($w / 2),floor($h / 2),$w,$h, rand(90,180),rand(180,270),$colorlist[$colorrandom]); } } imagegif($image); imagedestroy($image); $imagedata[]=ob_get_contents(); ob_clean(); ++$i; } $gif=new gifencoder($imagedata); header('content-type:image/gif'); echo $gif->getanimation(); } /** *gifencoder类 **/ class gifencoder{ var $gif="gif89a"; /* gif header 6 bytes */ var $ver="gifencoder v2.06"; /* encoder version */ var $buf=array(); var $lop=0; var $dis=2; var $col=-1; var $img=-1; var $err=array( 'err00'=>"does not supported function for only one image!", 'err01'=>"source is not a gif image!", 'err02'=>"unintelligible flag ", 'err03'=>"could not make animation from animated gif source", ); function gifencoder($gif_src,$gif_dly=100,$gif_lop=0,$gif_dis=0, $gif_red=0,$gif_grn=0,$gif_blu=0,$gif_mod='bin'){ if(!is_array($gif_src)&&!is_array($gif_tim)){ printf("%s: %s",$this->ver,$this->err['err00']); exit(0); } $this->lop=($gif_lop>-1)?$gif_lop:0; $this->dis=($gif_dis>-1)?(($gif_dis<3)?$gif_dis:3):2; $this->col=($gif_red>-1&&$gif_grn>-1&&$gif_blu>-1)?($gif_red |($gif_grn<<8)|($gif_blu<<16)):-1; for($i=0,$src_count=count($gif_src);$i<$src_count;$i++){ if(strtolower($gif_mod)=="url"){ $this->buf[]=fread(fopen($gif_src [$i],"rb"),filesize($gif_src [$i])); }elseif(strtolower($gif_mod)=="bin"){ $this->buf [ ]=$gif_src [ $i ]; }else{ printf("%s: %s(%s)!",$this->ver,$this->err [ 'err02' ],$gif_mod); exit(0); } if(substr($this->buf[$i],0,6)!="gif87a"&&substr($this->buf [$i],0,6)!="gif89a"){ printf("%s: %d %s",$this->ver,$i,$this->err ['err01']); exit(0); } for($j=(13+3*(2<<(ord($this->buf[$i]{10})&0x07))),$k=true;$k;$j++){ switch($this->buf [$i]{$j}){ case "!": if((substr($this->buf[$i],($j+3),8))=="netscape"){ printf("%s: %s(%s source)!",$this->ver,$this->err ['err03'],($i+1)); exit(0); } break; case ";": $k=false; break; } } } gifencoder::gifaddheader(); for($i=0,$count_buf=count($this->buf);$i<$count_buf;$i++){ gifencoder::gifaddframes($i,$gif_dly[$i]); } gifencoder::gifaddfooter(); } function gifaddheader(){ $cmap=0; if(ord($this->buf[0]{10})&0x80){ $cmap=3*(2<<(ord($this->buf [0]{10})&0x07)); $this->gif.=substr($this->buf [0],6,7); $this->gif.=substr($this->buf [0],13,$cmap); $this->gif.="!\377\13netscape2.0\3\1".gifencoder::gifword($this->lop)."\0"; } } function gifaddframes($i,$d){ $locals_str=13+3*(2 <<(ord($this->buf[$i]{10})&0x07)); $locals_end=strlen($this->buf[$i])-$locals_str-1; $locals_tmp=substr($this->buf[$i],$locals_str,$locals_end); $global_len=2<<(ord($this->buf [0]{10})&0x07); $locals_len=2<<(ord($this->buf[$i]{10})&0x07); $global_rgb=substr($this->buf[0],13,3*(2<<(ord($this->buf[0]{10})&0x07))); $locals_rgb=substr($this->buf[$i],13,3*(2<<(ord($this->buf[$i]{10})&0x07))); $locals_ext="!\xf9\x04".chr(($this->dis<<2)+0).chr(($d>>0)&0xff).chr(($d>>8)&0xff)."\x0\x0"; if($this->col>-1&&ord($this->buf[$i]{10})&0x80){ for($j=0;$j<(2<<(ord($this->buf[$i]{10})&0x07));$j++){ if(ord($locals_rgb{3*$j+0})==($this->col>> 0)&0xff&&ord($locals_rgb{3*$j+1})==($this->col>> 8)&0xff&&ord($locals_rgb{3*$j+2})==($this->col>>16)&0xff){ $locals_ext="!\xf9\x04".chr(($this->dis<<2)+1).chr(($d>>0)&0xff).chr(($d>>8)&0xff).chr($j)."\x0"; break; } } } switch($locals_tmp{0}){ case "!": $locals_img=substr($locals_tmp,8,10); $locals_tmp=substr($locals_tmp,18,strlen($locals_tmp)-18); break; case ",": $locals_img=substr($locals_tmp,0,10); $locals_tmp=substr($locals_tmp,10,strlen($locals_tmp)-10); break; } if(ord($this->buf[$i]{10})&0x80&&$this->img>-1){ if($global_len==$locals_len){ if(gifencoder::gifblockcompare($global_rgb,$locals_rgb,$global_len)){ $this->gif.=($locals_ext.$locals_img.$locals_tmp); }else{ $byte=ord($locals_img{9}); $byte|=0x80; $byte&=0xf8; $byte|=(ord($this->buf [0]{10})&0x07); $locals_img{9}=chr($byte); $this->gif.=($locals_ext.$locals_img.$locals_rgb.$locals_tmp); } }else{ $byte=ord($locals_img{9}); $byte|=0x80; $byte&=0xf8; $byte|=(ord($this->buf[$i]{10})&0x07); $locals_img {9}=chr($byte); $this->gif.=($locals_ext.$locals_img.$locals_rgb.$locals_tmp); } }else{ $this->gif.=($locals_ext.$locals_img.$locals_tmp); } $this->img=1; } function gifaddfooter(){ $this->gif.=";"; } function gifblockcompare($globalblock,$localblock,$len){ for($i=0;$i<$len;$i++){ if($globalblock{3*$i+0}!=$localblock{3*$i+0}||$globalblock{3*$i+1}!=$localblock{3*$i+1}||$globalblock{3*$i+2}!=$localblock{3*$i+2}){ return(0); } } return(1); } function gifword($int){ return(chr($int&0xff).chr(($int>>8)&0xff)); } function getanimation(){ return($this->gif); } }
加减验证:
<?php namespace mobile\components; /** * @author fenghuo * * 改造的加减法验证类 * 使用示例 verifycode::get(1,2); * 验证示例 verifycode::check($code); */ class verifycode { /** * php验证码 */ public static function get($one,$two,$prefix = '', $font_size = 28) { //文件头... ob_get_clean(); header("content-type: image/png;charset=utf-8;"); //创建真彩色白纸 $width = $font_size*5; $height = $font_size+1; $im = @imagecreatetruecolor($width, $height) or die("建立图像失败"); //获取背景颜色 $background_color = imagecolorallocate($im, 255, 255, 255); //填充背景颜色 imagefill($im, 0, 0, $background_color); //获取边框颜色 $border_color = imagecolorallocate($im, 200, 200, 200); //画矩形,边框颜色200,200,200 imagerectangle($im,0,0,$width - 1, $height - 1,$border_color); //逐行炫耀背景,全屏用1或0 for($i = 2;$i < $height - 2;$i++) { //获取随机淡色 $line_color = imagecolorallocate($im, rand(200,255), rand(200,255), rand(200,255)); //画线 imageline($im, 2, $i, $width - 1, $i, $line_color); } //设置印上去的文字 $firstnum = $one; $secondnum = $two; $actionstr = $firstnum > $secondnum ? '-' : '+'; //获取第1个随机文字 $imstr[0]["s"] = $firstnum; $imstr[0]["x"] = rand(2, 5); $imstr[0]["y"] = rand(1, 4); //获取第2个随机文字 $imstr[1]["s"] = $actionstr; $imstr[1]["x"] = $imstr[0]["x"] + $font_size - 1 + rand(0, 1); $imstr[1]["y"] = rand(1,5); //获取第3个随机文字 $imstr[2]["s"] = $secondnum; $imstr[2]["x"] = $imstr[1]["x"] + $font_size - 1 + rand(0, 1); $imstr[2]["y"] = rand(1, 5); //获取第3个随机文字 $imstr[3]["s"] = '='; $imstr[3]["x"] = $imstr[2]["x"] + $font_size - 1 + rand(0, 1); $imstr[3]["y"] = 3; //获取第3个随机文字 $imstr[4]["s"] = '?'; $imstr[4]["x"] = $imstr[3]["x"] + $font_size - 1 + rand(0, 1); $imstr[4]["y"] = 3; //文字 $text = ''; //写入随机字串 for($i = 0; $i < 5; $i++) { //获取随机较深颜色 $text_color = imagecolorallocate($im, rand(50, 180), rand(50, 180), rand(50, 180)); $text .= $imstr[$i]["s"]; //画文字 imagechar($im, $font_size, $imstr[$i]["x"], $imstr[$i]["y"], $imstr[$i]["s"], $text_color); } session_start(); $_session[$prefix.'verifycode'] = $firstnum > $secondnum ? ($firstnum - $secondnum) : ($firstnum + $secondnum); //显示图片 imagepng($im); //销毁图片 imagedestroy($im); } public static function check($code) { if(trim($_session[$prefix.'verifycode']) == trim($code)) { return true; } else { return false; } } }
yi 简单验证码:
1.验证码为全自动区分计算机和人类的图灵测试的缩写。是一种区分用户是计算机和人的公共全自动程序。
2.验证码主要应用场景:登录、注册确定前,发布、回复信息前,疑似机器请求时,做人/机器校验。
3.实现步骤:
(1)生成底图;
依赖php图片处理库gd,http://php.net/manual/zh/book.image.php
(2)生成验证内容;
产生随机数,使用php函数rand();
(3)生成验证码图片;
(4)校验验证内容
需要php操作session基础,将验证内容保存在服务器端;前端ajax基础
4.开发前的准备:
(1)php运行环境
(2)检查php是否支持gd,通过在php文件中使用函数 phpinfo()输出查看即可。
1.新建一个captcha.php文件,写入下列代码。实现验证码图片
<?php //必须至于顶部,多服务器端记录验证码信息,便于用户输入后做校验 session_start(); //默认返回的是黑色的照片 $image = imagecreatetruecolor(100, 30); //将背景设置为白色的 $bgcolor = imagecolorallocate($image, 255, 255, 255); //将白色铺满地图 imagefill($image, 0, 0, $bgcolor); //空字符串,每循环一次,追加到字符串后面 $captch_code=''; //验证码为随机四个数字 for ($i=0; $i < 4; $i++) { $fontsize=6; $fontcolor=imagecolorallocate($image,rand(0,120),rand(0,120),rand(0,120)); //产生随机数字0-9 $fontcontent = rand(0,9); $captch_code.= $fontcontent; //数字的位置,0,0是左上角。不能重合显示不完全 $x=($i*100/4)+rand(5,10); $y=rand(5,10); imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor); } $_session['authcode'] = $captch_code; //为验证码增加干扰元素,控制好颜色, //点 for ($i=0; $i < 200; $i++) { $pointcolor = imagecolorallocate($image,rand(50,200),rand(50,200),rand(50,200)); imagesetpixel($image, rand(1,99), rand(1,29), $pointcolor); } //为验证码增加干扰元素线 for ($i=0; $i < 3; $i++) { $linecolor = imagecolorallocate($image,rand(80,220),rand(80,220),rand(80,220)); imageline($image, rand(1,99), rand(1,29),rand(1,99), rand(1,29) ,$linecolor); } header('content-type:image/png'); imagepng($image); //销毁 imagedestroy($image);
查看效果如下:刷新一次,内容或会变化一次;
2.新建一个form.php文件,写入下列代码。实现校验:
<?php if (isset($_request['authcode'])) { session_start(); if (strtolower($_request['authcode'])==$_session['authcode']) { echo'<font color ="#0000cc"> 输出正确</font>'; # code... }else{ echo $_request['authcode']; echo $_session['authcode']; echo'<font color ="#cc0000"> 输出错误</font>'; } exit(); } ?> <!doctype html> <html> <head> <meta charset="utf-8" /> <title>确认验证码</title> </head> <body> <form method="" ="post" action="./form.php"> <p>验证码图片: <img id="captcha_img" border="1" src="./captcha.php?r=<?php echo rand(); ?>" alt="" width="100" height="30"> <a href="javascript:void(0)" οnclick="document.getelementbyid('captcha_img').src='./captcha.php?r='+math.random() ">换一个?</a> </p> <p>请输入图片中的内容: <input type="text" name="authcode" value="" /> </p> <p> <input type="submit" value="提交" style="padding: 6px 20px;"> </p> </form> </body> </html>
实现结果如下,点击换一个,会换一个验证码。 输入图片中内容,如果正确,提示输入正确,如果错误,提示输入错误。样式自行修改。
er 数字字母验证码:
1.生成验证码图片,只需将产生随机数字的代码换成产生随机数字字母的代码,其他代码与二中保持一致
//验证码为随机四个字符,数字和字母 for ($i=0; $i <4 ; $i++) { $fontsize=6; $fontcolor=imagecolorallocate($image,rand(0,120),rand(0,120),rand(0,120)); //子典。因为o和0,l和1冲突,所以我们字典中不包括易混淆的 $data='abcdefghijkmnpqrstuvwxy3456789'; $fontcontent = substr($data,rand(0,strlen($data)) ,1); $captch_code.= $fontcontent; $x=($i*100/4)+rand(5,10); $y=rand(5,10); imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor); }
效果如下:
san:汉字验证码
<?php //设置session,必须处于脚本最顶部 session_start(); //设置验证码图片大小的函数 $image = imagecreatetruecolor(200, 60); //设置验证码颜色 imagecolorallocate(int im, int red, int green, int blue); $bgcolor = imagecolorallocate($image,255,255,255); //#ffffff //区域填充 int imagefill(int im, int x, int y, int col) (x,y) 所在的区域着色,col 表示欲涂上的颜色 imagefill($image, 0, 0, $bgcolor); //设置ttf字体 $fontface = 'fzytk.ttf'; //设置字库,实现简单的数字储备 $str='天地不仁以万物为刍狗圣人不仁以百姓为刍狗这句经常出现在控诉暴君暴政上地残暴不仁把万物都当成低贱的猪狗来看待而那些高高在上的所谓圣人们也没两样还不是把我们
老百姓也当成猪狗不如的东西但实在正取的解读是地不情感用事对万物一视同仁圣人不情感用事对百姓一视同仁执子之手与子偕老当男女主人公含情脉脉看着对方说了句执子之手与子
偕老女方泪眼朦胧含羞地回一句讨厌啦这样的情节我们是不是见过很多但是我们来看看这句的原句死生契阔与子成说执子之手与子偕老于嗟阔兮不我活兮于嗟洵兮不我信兮意思是说
战士之间的约定说要一起死现在和我约定的人都走了我怎么活啊赤裸裸的兄弟江湖战友友谊啊形容好基友的基情比男女之间的爱情要合适很多吧'; //str_split()切割字符串为一个数组,一个中文在utf_8为3个字符 $strdb = str_split($str,3); // $captcha_code = ''; //生成随机的汉子 for($i=0;$i<4;$i++){ //设置字体颜色,随机颜色 $fontcolor = imagecolorallocate($image, rand(0,120),rand(0,120), rand(0,120)); //0-120深颜色 //随机选取中文 $in = rand(0,count($strdb)); $cn = $strdb[$in]; //将中文记录到将保存到session的字符串中 $captcha_code .= $cn; /*imagettftext (resource $image ,float $size ,float $angle ,int $x ,int $y,int $color, string $fontfile ,string $text ) 幕布 ,尺寸,角度,坐标,颜色,字体路径,文本字符串 mt_rand()生成更好的随机数,比rand()快四倍*/ imagettftext($image, mt_rand(20,24),mt_rand(-60,60),(40*$i+20),mt_rand(30,35),$fontcolor,$fontface,$cn); } //存到session $_session['authcode'] = $captcha_code; //增加干扰元素,设置点 for($i=0;$i<200;$i++){ //设置点的颜色,50-200颜色比数字浅,不干扰阅读 $pointcolor = imagecolorallocate($image,rand(50,200), rand(50,200), rand(50,200)); //imagesetpixel — 画一个单一像素 imagesetpixel($image, rand(1,199), rand(1,59), $pointcolor); } //增加干扰元素,设置线 for($i=0;$i<4;$i++){ //设置线的颜色 $linecolor = imagecolorallocate($image,rand(80,220), rand(80,220),rand(80,220)); //设置线,两点一线 imageline($image,rand(1,199), rand(1,59),rand(1,199), rand(1,59),$linecolor); } //设置头部,image/png header('content-type: image/png'); //imagepng() 建立png图形函数 imagepng($image); //imagedestroy() 结束图形函数 销毁$image imagedestroy($image);
//接着就是静态页的代码了: doctype html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>确认验证码</title> </head> <body> <form method="post" action="./form.php"> <p>验证码: <img id="captcha_img" border='1' src='./captcha.php?r=echo rand(); ?>' style="width:100px; height:30px" /> <a href="javascript:void(0)" onclick="document.getelementbyid('captcha_img').src='./captcha.php?r='+math.random()">换一个?</a>
</p> <p>请输入验证码:<input type="text" name='authcode' value=''/></p> <p><input type='submit' value='提交' style='padding:6px 5px;'/></p> </body> </html> //从html可以看到,提交的表单是到php的,所以还要有一个判断的php代码: <?php header("content-type:text/html;charset=utf-8"); //设置头部信息 //isset()检测变量是否设置 if(isset($_request['authcode'])){ session_start(); //strtolower()小写函数 if(strtolower($_request['authcode'])== $_session['authcode']){ //跳转页面 echo "<script language=\"javascript\">"; echo "document.location=\"./php\""; echo "</script>"; }else{ //提示以及跳转页面 echo "<script language=\"javascript\">"; echo "alert('输入错误!');"; echo "document.location=\"./php\""; echo "</script>"; } exit(); } php?>