I haven’t written a post for a long time. Always busy with new projects. Recently, I have been working on a verification code program, and I have always wanted to make it simple and elegant, but it is difficult to automatically identify it. Through these collections, I found that the general approach has the following solutions:
1. Font variation (generally distorted through algorithms, the more representative one is: http://code.google.com/p /cool-php-captcha/
2. Font pasting (the QQ verification code is represented here. It is still difficult to find online and crack the QQ verification code)
3. Interference lines and noise points (this kind of identification is quite easy and can be automatically identified by the program)
For the above mentioned, the 1st and 2nd methods, during identification, is more difficult. Personally, I prefer the second method, as it doesn't seem very laborious. And the twisted text always feels weird. Haha, purely personal preference.
Implementation code:
Copy code The code is as follows:
/**
*With text rotation, tilting, pasting, and adding sine interference line verification code*
*@version 0.1
*@author http://www.cnblogs.com/chengmo
*@copyright Cheng Mo QQ:8292669
*/
class Utils_Caption
{
var $Width = 60; //Image width
var $Height = 30; //Picture height
var $Length = 4; //Verification code digits
var $BgColor = "#FFFFFF"; //Background color
var $TFonts = array("font.ttf ");
var $TFontSize=array(17,20); //Font size range
var $TFontAngle=array(-20,20); //Rotation angle
var $Chars = "0123456789 "; //Verification code range (alphanumeric)
var $Code = array(); //Verification code
var $Image = ""; // Graphic object
var $FontColors=array(' #f36161','#6bc146','#5368bd'); //Font color, red, green and blue
var $TPadden = 0.75;///Character spacing, how many characters
var $Txbase = 5; ///The distance on both sides of the x-axis
var $Tybase =5;///The distance on both sides of the y-axis
var $TLine =true; ///Draw interference lines
public function RandRSI() ///Generate Verification code
{
$this->TFontAngle=range($this->TFontAngle[0],$this->TFontAngle[1]);
$this->TFontSize=range ($this->TFontSize[0],$this->TFontSize[1]);
$arr=array();
$Chars=$this->Chars;
$TFontAngle =$this->TFontAngle;
$TFontSize=$this->TFontSize;
$FontColors=$this->FontColors;
$code="";
$font=dirname (__FILE__)."/font/".$this->TFonts[0];
$charlen=strlen($Chars)-1;
$anglelen=count($TFontAngle)-1; // Angle range
$fontsizelen=count($TFontSize)-1; // Angle range
$fontcolorlen=count($FontColors)-1; // Angle range
for($i=0;$i< ;$this->Length;$i++) ///Get the character and color
{
$char=$Chars[rand(0,$charlen)]; ///Get the character
$angle =$TFontAngle[rand(0,$anglelen)]; ///Rotation angle
$fontsize=$TFontSize[rand(0,$fontsizelen)]; ///Font size
$fontcolor=$FontColors[ rand(0,$fontcolorlen)]; ///Font size
$bound=$this->_calculateTextBox($fontsize,$angle,$font,$char); ///Get range
$arr []=array($fontsize,$angle,$fontcolor,$char,$font,$bound); ///Get the rectangular frame
$code.=$char;
}
$this- >Code=$arr; //Verification code
return $code;
}
public function Draw() ///Draw
{
if(empty($this-> Code)) $this->RandRSI();
$codes=$this->Code; ///User verification code
$wh=$this->_getImageWH($codes);
$width=$wh[0];
$height=$wh[1]; ///Height
$this->Width=$width;
$this->Height=$ height;
$this->Image = imageCreate( $width, $height );
$image=$this->Image;
$back = $this->_getColor2($this- >_getColor( $this->BgColor)); ///Background color
imageFilledRectangle($image, 0, 0, $width, $height, $back); ///Filled background
$TPadden =$this->TPadden;
$basex=$this->Txbase;
$color=null;
foreach ($codes as $v) ///Draw characters one by one
{
$bound=$v[5];
$color=$this->_getColor2($this->_getColor($v[2]));
imagettftext($image, $v [0], $v[1], $basex, $bound['height'],$color , $v[4], $v[3]);
$basex=$basex+$bound['width ']*$TPadden-$bound['left'];///Calculate the next left margin
}
$this->TLine?$this->_wirteSinLine($color,$basex): null; ///Draw interference lines
header("Content-type: image/png");
imagepng( $image);
imagedestroy($image);
}
/**
*Get the font rectangle width through the font angle*
*
* @param int $font_size font size
* @param float $font_angle rotation angle
* @param string $font_file font file path
* @param string $text Write characters
* @return array Return length, width and height
*/
private function _calculateTextBox($font_size, $font_angle, $font_file, $text) {
$box = imagettfbbox($font_size, $font_angle, $font_file, $text);
$min_x = min(array($box[0], $box[2], $box[4], $box[6]));
$max_x = max(array($box[0], $box[2], $box[4], $box[6]));
$min_y = min(array($box[1], $box[3], $box[5], $box[7]));
$max_y = max(array($box[1], $box[3], $box[5], $box[7]));
return array(
'left' => ($min_x >= -1) ? -abs($min_x + 1) : abs($min_x + 2),
'top' => abs($min_y),
'width' => $max_x - $min_x,
'height' => $max_y - $min_y,
'box' => $box
);
}
private function _getColor( $color ) //#ffffff
{
return array(hexdec($color[1].$color[2]),hexdec($color[3].$color[4]),hexdec($color[5].$color[6]));
}
private function _getColor2( $color ) //#ffffff
{
return imagecolorallocate ($this->Image, $color[0], $color[1], $color[2]);
}
private function _getImageWH($data)
{
$TPadden=$this->TPadden;
$w=$this->Txbase;
$h=0;
foreach ($data as $v)
{
$w=$w+$v[5]['width']*$TPadden-$v[5]['left'];
$h=$h>$v[5]['height']?$h:$v[5]['height'];
}
return array(max($w,$this->Width),max($h,$this->Height));
}
//画正弦干扰线
private function _wirteSinLine($color,$w)
{
$img=$this->Image;
$h=$this->Height;
$h1=rand(-5,5);
$h2=rand(-1,1);
$w2=rand(10,15);
$h3=rand(4,6);
for($i=-$w/2;$i<$w/2;$i=$i+0.1)
{
$y=$h/$h3*sin($i/$w2)+$h/2+$h1;
imagesetpixel($img,$i+$w/2,$y,$color);
$h2!=0?imagesetpixel($img,$i+$w/2,$y+$h2,$color):null;
}
}
}
外带字体:
font.ttf ,一个简单粗体文件。
说明:先看下运行效果吧,大家也不要忙着复制运行了。
主要特点是:旋转,然后黏贴,干扰线是线粗细可以变,然后正弦波形可以变化。
比较复杂是:calculateTextBox 这个函数,这个是得到字符旋转后的宽度高度。
demo:
复制代码 代码如下:
$rsi = new Utils_Caption();
$rsi->TFontSize=array(15,17);
$rsi->Width=50;
$rsi->Height=25;
$code = $rsi->RandRSI();
session_start();
$_SESSION["CHECKCODE"] = $code;
$rsi->Draw();
好了,就写这么些了,代码还有很多不足之处。
点击下载代码
http://www.bkjia.com/PHPjc/327913.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/327913.htmlTechArticle好久没有写帖子了。一直忙着新的项目。 最近,做验证码程序,一直想做一个简洁大方,自动识别比较困难的。 通过这些时候整理搜集,发...