字体变型 (一般通过算法进行扭曲比较有代表性就是
字体黏贴 (这里面以qq验证码为代表了目前网上还是很难找到破解qq验证码的)
干扰线噪点 (这种识别起来相当容易很容易被程序自动化识别)
对于上面提到第 二种方法在识别时候是比较困难的个人比较喜欢第二种方法感觉看起来不是很费力而扭曲的文字总觉得怪怪的 哈哈纯粹个人喜好了
实现代码
<?php/** *带文字旋转倾斜黏贴加正弦干扰线验证码* *@version *@author *@copyright 程默 QQ: */class Utils_Caption{var $Width = ; //图片宽var $Height = ; //图片高var $Length = ; //验证码位数var $BgColor = "#FFFFFF"; //背景色var $TFonts = array("fontttf");var $TFontSize=array(); //字体大小范围var $TFontAngle=array(); //旋转角度var $Chars = ""; //验证码范围(字母数字)var $Code = array(); //验证码var $Image = ""; //图形对象var $FontColors=array(#f#bc#bd); //字体颜色红绿蓝var $TPadden = ;///字符间距多少个字符var $Txbase = ;///x轴两边距离var $Tybase = ;///y轴两边距离var $TLine =true; ///画干扰线public function RandRSI() ///生成验证码{$this>TFontAngle=range($this>TFontAngle[]$this>TFontAngle[]);$this>TFontSize=range($this>TFontSize[]$this>TFontSize[]);$arr=array();$Chars=$this>Chars;$TFontAngle=$this>TFontAngle;$TFontSize=$this>TFontSize;$FontColors=$this>FontColors;$code="";$font=dirname(__FILE__)"/font/"$this>TFonts[];$charlen=strlen($Chars);$anglelen=count($TFontAngle); // 角度范围$fontsizelen=count($TFontSize); // 角度范围$fontcolorlen=count($FontColors); // 角度范围for($i=;$i<$this>Length;$i++) ///得到字符与颜色{$char=$Chars[rand($charlen)]; ///得到字符$angle=$TFontAngle[rand($anglelen)]; ///旋转角度$fontsize=$TFontSize[rand($fontsizelen)]; ///字体大小$fontcolor=$FontColors[rand($fontcolorlen)]; ///字体大小$bound=$this>_calculateTextBox($fontsize$angle$font$char); ///得到范围$arr[]=array($fontsize$angle$fontcolor$char$font$bound); ///得到矩形框$code=$char;}$this>Code=$arr; //验证码return $code;}public function Draw() ///画图{if(empty($this>Code)) $this>RandRSI();$codes=$this>Code; ///用户验证码$wh=$this>_getImageWH($codes);$width=$wh[];$height=$wh[]; ///高度$this>Width=$width;$this>Height=$height;$this>Image = imageCreate( $width $height );$image=$this>Image;$back = $this>_getColor($this>_getColor( $this>BgColor)); ///背景颜色imageFilledRectangle($image $width $height $back); ///填充背景$TPadden=$this>TPadden;$basex=$this>Txbase;$color=null;foreach ($codes as $v) ///逐个画字符{$bound=$v[];$color=$this>_getColor($this>_getColor($v[]));imagettftext($image $v[] $v[] $basex $bound[height]$color $v[] $v[]);$basex=$basex+$bound[width]*$TPadden$bound[left];///计算下一个左边距}$this>TLine?$this>_wirteSinLine($color$basex):null; ///画干扰线header("Contenttype: image/png");imagepng( $image);imagedestroy($image);}/** *通过字体角度得到字体矩形宽度* * * @param int $font_size 字体尺寸 * @param float $font_angle 旋转角度 * @param string $font_file 字体文件路径 * @param string $text 写入字符 * @return array 返回长宽高 */private function _calculateTextBox($font_size $font_angle $font_file $text) {$box = imagettfbbox($font_size $font_angle $font_file $text);$min_x = min(array($box[] $box[] $box[] $box[]));$max_x = max(array($box[] $box[] $box[] $box[]));$min_y = min(array($box[] $box[] $box[] $box[]));$max_y = max(array($box[] $box[] $box[] $box[]));return array(left => ($min_x >= ) ? abs($min_x + ) : abs($min_x + )top => abs($min_y)width => $max_x $min_xheight => $max_y $min_ybox => $box);}private function _getColor( $color ) //#ffffff{return array(hexdec($color[]$color[])hexdec($color[]$color[])hexdec($color[]$color[]));}private function _getColor( $color ) //#ffffff{return imagecolorallocate ($this>Image $color[] $color[] $color[]);}private function _getImageWH($data){$TPadden=$this>TPadden;$w=$this>Txbase;$h=;foreach ($data as $v){$w=$w+$v[][width]*$TPadden$v[][left];$h=$h>$v[][height]?$h:$v[][height];}return array(max($w$this>Width)max($h$this>Height));}//画正弦干扰线private function _wirteSinLine($color$w){$img=$this>Image;$h=$this>Height;$h=rand();$h=rand();$w=rand();$h=rand();for($i=$w/;$i<$w/;$i=$i+){$y=$h/$h*sin($i/$w)+$h/+$h;imagesetpixel($img$i+$w/$y$color);$h!=?imagesetpixel($img$i+$w/$y+$h$color):null;}}}
外带字体
fontttf 一个简单粗体文件
说明
先看下运行效果吧大家也不要忙着复制运行了
……
主要特点是旋转然后黏贴干扰线是线粗细可以变然后正弦波形可以变化
比较复杂是calculateTextBox 这个函数这个是得到字符旋转后的宽度高度
demo:
$rsi = new Utils_Caption();$rsi>TFontSize=array();$rsi>Width=;$rsi>Height=;$code = $rsi>RandRSI();session_start();$_SESSION["CHECKCODE"] = $code;$rsi>Draw();
好了就写这么些了代码还有很多不足之处欢迎朋友提出好的建议