php生成復(fù)雜驗(yàn)證碼(傾斜,正弦干擾線,黏貼,旋轉(zhuǎn))
現(xiàn)在好多網(wǎng)站使用的驗(yàn)證碼非常容易被軟件自動(dòng)識(shí)別到,本文介紹了一種PHP生成復(fù)雜驗(yàn)證碼加入傾斜,弦干擾線,黏貼,旋轉(zhuǎn)等效果
常見(jiàn)的軟件不容易自動(dòng)識(shí)別的驗(yàn)證碼做法有以下3種:
1、字體變型 (一般通過(guò)算法,進(jìn)行扭曲)
2、字體黏貼 (這里面以qq驗(yàn)證碼為代表了,目前網(wǎng)上還是很難找到,破解qq驗(yàn)證碼的)
3、干擾線,噪點(diǎn) (這種識(shí)別起來(lái)相當(dāng)容易,很容易被程序自動(dòng)化識(shí)別)
對(duì)于上面提到,第1,2 二種方法,在識(shí)別時(shí)候,是比較困難的。
具體實(shí)現(xiàn)代碼:
<?php /** *帶文字旋轉(zhuǎn),傾斜,黏貼,加正弦干擾線驗(yàn)證碼* */ class Utils_Caption { var $Width = 60; //圖片寬 var $Height = 30; //圖片高 var $Length = 4; //驗(yàn)證碼位數(shù) var $BgColor = "#FFFFFF"; //背景色 var $TFonts = array("font.ttf"); var $TFontSize=array(17,20); //字體大小范圍 var $TFontAngle=array(-20,20); //旋轉(zhuǎn)角度 var $Chars = "0123456789"; //驗(yàn)證碼范圍(字母數(shù)字) var $Code = array(); //驗(yàn)證碼 var $Image = ""; //圖形對(duì)象 var $FontColors=array('#f36161','#6bc146','#5368bd'); //字體顏色,紅綠藍(lán) var $TPadden = 0.75;///字符間距,多少個(gè)字符 var $Txbase = 5;///x軸兩邊距離 var $Tybase =5 ;///y軸兩邊距離 var $TLine =true; ///畫干擾線 public function RandRSI() ///生成驗(yàn)證碼 { $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; // 角度范圍 $fontsizelen=count($TFontSize)-1; // 角度范圍 $fontcolorlen=count($FontColors)-1; // 角度范圍 for($i=0;$i<$this->Length;$i++) ///得到字符與顏色 { $char=$Chars[rand(0,$charlen)]; ///得到字符 $angle=$TFontAngle[rand(0,$anglelen)]; ///旋轉(zhuǎn)角度 $fontsize=$TFontSize[rand(0,$fontsizelen)]; ///字體大小 $fontcolor=$FontColors[rand(0,$fontcolorlen)]; ///字體大小 $bound=$this->_calculateTextBox($fontsize,$angle,$font,$char); ///得到范圍 $arr[]=array($fontsize,$angle,$fontcolor,$char,$font,$bound); ///得到矩形框 $code.=$char; } $this->Code=$arr; //驗(yàn)證碼 return $code; } public function Draw() ///畫圖 { if(empty($this->Code)) $this->RandRSI(); $codes=$this->Code; ///用戶驗(yàn)證碼 $wh=$this->_getImageWH($codes); $width=$wh[0]; $height=$wh[1]; ///高度 $this->Width=$width; $this->Height=$height; $this->Image = imageCreate( $width, $height ); $image=$this->Image; $back = $this->_getColor2($this->_getColor( $this->BgColor)); ///背景顏色 imageFilledRectangle($image, 0, 0, $width, $height, $back); ///填充背景 $TPadden=$this->TPadden; $basex=$this->Txbase; $color=null; foreach ($codes as $v) ///逐個(gè)畫字符 { $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'];///計(jì)算下一個(gè)左邊距 } $this->TLine?$this->_wirteSinLine($color,$basex):null; ///畫干擾線 header("Content-type: image/png"); imagepng( $image); imagedestroy($image); } /** *通過(guò)字體角度得到字體矩形寬度* * * @param int $font_size 字體尺寸 * @param float $font_angle 旋轉(zhuǎn)角度 * @param string $font_file 字體文件路徑 * @param string $text 寫入字符 * @return array 返回長(zhǎng)寬高 */ 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; } } }
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();
運(yùn)行效果:
大家可以修改代碼中的相應(yīng)數(shù)值達(dá)到自己需要的復(fù)雜度
- PHP圖像處理技術(shù)實(shí)例總結(jié)【繪圖、水印、驗(yàn)證碼、圖像壓縮】
- php實(shí)現(xiàn)算術(shù)驗(yàn)證碼功能
- PHP封裝的驗(yàn)證碼工具類定義與用法示例
- PHP實(shí)現(xiàn)隨機(jī)數(shù)字、字母的驗(yàn)證碼功能
- PHP驗(yàn)證碼類文件及調(diào)用方式代碼詳解
- PHP使用GD庫(kù)制作驗(yàn)證碼的方法(點(diǎn)擊驗(yàn)證碼或看不清會(huì)刷新驗(yàn)證碼)
- 一個(gè)漂亮的php驗(yàn)證碼類(分享)
- PHP生成圖片驗(yàn)證碼、點(diǎn)擊切換實(shí)例
- 如何打開(kāi)php的gd2庫(kù)
- 基于GD2圖形庫(kù)的PHP生成圖片縮略圖類代碼分享
- PHP基于GD2函數(shù)庫(kù)實(shí)現(xiàn)驗(yàn)證碼功能示例
相關(guān)文章
shell編程入門之變量,字符串,數(shù)組,函數(shù)使用方法總結(jié)
這篇文章主要介紹了shell編程入門之變量,字符串,數(shù)組,函數(shù)使用方法總結(jié),需要的朋友可以參考下2022-01-01php計(jì)數(shù)器的設(shè)計(jì)與實(shí)現(xiàn)
php計(jì)數(shù)器的設(shè)計(jì)與實(shí)現(xiàn)...2006-07-07php網(wǎng)絡(luò)安全session利用的小思路
這篇文章主要為大家介紹了關(guān)于php網(wǎng)絡(luò)安全中session利用的小思路示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02從零開(kāi)始 教你如何搭建Discuz!4.1論壇(圖)
從零開(kāi)始 教你如何搭建Discuz!4.1論壇(圖)...2006-07-07eval(cmd)與eval($cmd)的區(qū)別與聯(lián)系
這篇文章主要介紹了eval(cmd)與eval($cmd)的區(qū)別與聯(lián)系,希望對(duì)屏幕前的你有所幫助2021-07-07解決控件遮擋問(wèn)題:關(guān)于有窗口元素和無(wú)窗口元素
解決控件遮擋問(wèn)題:關(guān)于有窗口元素和無(wú)窗口元素...2007-01-01