php實現動態隨機驗證碼機制
驗證碼(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自動區分電腦和人類的圖靈測試)的縮寫,是一種區分使用者是電腦還是人的公用全Bot。可以防止:惡意破解密碼、刷票、論壇灌水,有效防止某個駭客對某一個特定註冊使用者用特定程式暴力破解方式進行不斷的登陸嘗試,實際上用驗證碼是現在很多網站通行的方式,我們利用比較簡易的方式實現了這個功能。
這個問題可以由電腦產生並評判,但是必須只有人類才能解答。由於電腦無法解答CAPTCHA的問題,所以回答出問題的使用者就可以被認為是人類。
Php製作動態驗證碼是基於php的影像處理,下面首先介紹一下php的影像處理。
一.php影像處理簡介
在PHP5中,動態圖象的處理要比以前容易得多。PHP5在php.ini檔案中包含了GD擴充包,只需去掉GD擴充包的相應注釋就可以正常使用了。PHP5包含的GD庫正是升級的GD2庫,其中包含支援真彩影像處理的一些有用的JPG功能。
一般產生的圖形,通過PHP的文檔格式存放,但可以通過HTML的圖片插入方式SRC來直接擷取動態圖形。比如,驗證碼、浮水印、微縮圖等。
建立映像的一般流程:
1).設定標題,告訴瀏覽器你要產生的MIME類型。
2).建立一個映像地區,以後的操作都將基於此映像地區。
3).在空白映像地區繪製填充背景。
4).在背景上繪製圖形輪廓輸入文本。
5).輸出最終圖形。
6).清除所有資源。
7).其他頁面調用映像。
第一步,設定檔案MIME類型,輸出類型 將輸出類型改成映像流
header('Content-Type: image/png;');
一般產生的映像可以是png,jpeg,gif,wbmp
第二步,建立一個繪圖區域,映像背景
imagecreatetruecolor() 返回一個映像標識符,代表了一幅大小為 x_size 和 y_size 的黑色映像。文法:resource imagecreatetruecolor ( int $width , int $height )
$im = imagecreatetruecolor(200,200);
第三步,在空白映像地區繪製填充背景
要有顏色填充器;imagecolorallocate -- 為一幅映像分配顏色;文法:int imagecolorallocate ( resource $image , int $red , int $green , int $blue )
$blue = imagecolorallocate($im,0,102,255);
將這個blue顏色填充到背景上去;imagefill -- 地區填充;文法:bool imagefill ( resource $image , int $x , int $y , int $color )
imagefill($im,0,0,$blue);
第四步,在藍色的背景上輸入一些線條,文字等
顏色填充器
$white = imagecolorallocate($im,255,255,255);
畫兩條線段:imageline
imageline() 用 color 顏色在映像 image 中從座標 x1,y1 到 x2,y2(映像左上方為 0, 0)畫一條線段。文法:bool imageline ( resource $image , int $x1 , int $y1 , int $x2 , int $y2 , int $color )
imageline($im,0,0,200,200,$white);
imageline($im,200,0,0,200,$white);
水平地畫一行字串:imagestring
imagestring() 用 col 顏色將字串 s 畫到 image 所代表的映像的 x,y 座標處(這是字串左上方座標,整幅映像的左上方為 0,0)。如果font 是 1,2,3,4 或 5,則使用內建字型。文法:bool imagestring ( resource $image , int $font , int $x , int $y , string $s , int $col )
imagestring($im,5,66,20,'jingwhale',$white);
第五步,輸出最終圖形
imagepng() 將 GD 映像流(image)以 PNG 格式輸出到標準輸出(通常為瀏覽器),或者如果用 filename 給出了檔案名稱則將其輸出到該檔案。文法:bool imagepng ( resource $image [, string $filename ] )
imagepng($im);
第六步,我要將所有的資源全部清空
imagedestroy() 釋放與 image 關聯的記憶體。文法:bool imagedestroy ( resource $image )
imagedestroy($im);
其他頁面(html)調用建立的圖形
範例程式碼如下:
php //第一步,設定檔案MIME類型 header('Content-Type: image/png;'); //第二步,建立一個繪圖區域,映像背景 $im = imagecreatetruecolor(200,200); //第三步,在空白映像地區繪製填充背景 $blue = imagecolorallocate($im,0,102,255); imagefill($im,0,0,$blue); //第四步,在藍色的背景上輸入一些線條,文字等 $white = imagecolorallocate($im,255,255,255); imageline($im,0,0,200,200,$white); imageline($im,200,0,0,200,$white); imagestring($im,5,66,20,'Jing.Whale',$white); //第五步,輸出最終圖形 imagepng($im); //第六步,我要將所有的資源全部清空 imagedestroy($im); ?>
顯示效果:
二.建立動態驗證碼
附:代碼源地址https://github.com/cnblogs-/php-captcha
1. 建立帶驗證碼的圖片,並模糊背景
隨機碼採用16進位;模糊背景即在圖片背景加上線條、雪花等。
1)建立隨機碼
for ($i=0;$i<$_rnd_code;$i++) { $_nmsg .= dechex(mt_rand(0,15)); }
string dechex ( int $number ),返回一字串,包含有給定 number 參數的十六進位表示。
2)儲存在session
$_SESSION['code'] = $_nms
3)建立圖片
//建立一張映像$_img = imagecreatetruecolor($_width,$_height);//白色$_white = imagecolorallocate($_img,255,255,255);//填充imagefill($_img,0,0,$_white);if ($_flag) {//黑色,邊框 $_black = imagecolorallocate($_img,0,0,0); imagerectangle($_img,0,0,$_width-1,$_height-1,$_black);}
4)模糊背景
//隨即畫出6個線條for ($i=0;$i<6;$i++) { $_rnd_color = imagecolorallocate($_img,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255)); imageline($_img,mt_rand(0,$_width),mt_rand(0,$_height),mt_rand(0,$_width),mt_rand(0,$_height),$_rnd_color); }//隨機雪花for ($i=0;$i<100;$i++) { $_rnd_color = imagecolorallocate($_img,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255)); imagestring($_img,1,mt_rand(1,$_width),mt_rand(1,$_height),'*',$_rnd_color); }
5)輸出及銷毀
//輸出驗證碼for ($i=0;$i<strlen($_SESSION['code']);$i++) { $_rnd_color = imagecolorallocate($_img,mt_rand(0,100),mt_rand(0,150),mt_rand(0,200)); imagestring($_img,5,$i*$_width/$_rnd_code+mt_rand(1,10),mt_rand(1,$_height/2),$_SESSION['code'][$i],$_rnd_color); }//輸出映像header('Content-Type: image/png');imagepng($_img);//銷毀imagedestroy($_img);
將其封裝在global.func.php全域函數庫中,函數名為_code(),以便調用。我們將設定$_width ,$_height ,$_rnd_code,$_flag 四個參數,以增強函數的靈活性。
* @param int $_width 驗證碼的長度:如果要6位長度推薦75+50;如果要8位,推薦75+50+50,依次類推
* @param int $_height 驗證碼的高度
* @param int $_rnd_code 驗證碼的位元
* @param bool $_flag 驗證碼是否需要邊框:true有邊框, false無邊框(預設)
封裝後的代碼如下:
php /** * [verification-code] (C)2015-2100 jingwhale. * * This is a freeware * $Id: global.func.php 2015-02-05 20:53:56 jingwhale$ */
/** * _code()是驗證碼函數 * @access public * @param int $_width 驗證碼的長度:如果要6位長度推薦75+50;如果要8位,推薦75+50+50,依次類推 * @param int $_height 驗證碼的高度 * @param int $_rnd_code 驗證碼的位元 * @param bool $_flag 驗證碼是否需要邊框:true有邊框, false無邊框(預設) * @return void 這個函數執行後產生一個驗證碼 */function _code($_width = 75,$_height = 25,$_rnd_code = 4,$_flag = false) { //建立隨機碼 for ($i=0;$i<$_rnd_code;$i++) { $_nmsg .= dechex(mt_rand(0,15)); } //儲存在session $_SESSION['code'] = $_nmsg; //建立一張映像 $_img = imagecreatetruecolor($_width,$_height); //白色 $_white = imagecolorallocate($_img,255,255,255); //填充 imagefill($_img,0,0,$_white); if ($_flag) { //黑色,邊框 $_black = imagecolorallocate($_img,0,0,0); imagerectangle($_img,0,0,$_width-1,$_height-1,$_black); } //隨即畫出6個線條 for ($i=0;$i<6;$i++) { $_rnd_color = imagecolorallocate($_img,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255)); imageline($_img,mt_rand(0,$_width),mt_rand(0,$_height),mt_rand(0,$_width),mt_rand(0,$_height),$_rnd_color); } //隨即雪花 for ($i=0;$i<100;$i++) { $_rnd_color = imagecolorallocate($_img,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255)); imagestring($_img,1,mt_rand(1,$_width),mt_rand(1,$_height),'*',$_rnd_color); } //輸出驗證碼 for ($i=0;$i<strlen($_SESSION['code']);$i++) { $_rnd_color = imagecolorallocate($_img,mt_rand(0,100),mt_rand(0,150),mt_rand(0,200)); imagestring($_img,5,$i*$_width/$_rnd_code+mt_rand(1,10),mt_rand(1,$_height/2),$_SESSION['code'][$i],$_rnd_color); } //輸出映像 header('Content-Type: image/png'); imagepng($_img); //銷毀 imagedestroy($_img);}?>
2.建立驗證機制
建立php驗證頁面,通過session來檢驗驗證碼是否一致。
1)建立verification-code.php驗證頁面
php /** * [verification-code] (C)2015-2100 jingwhale. * * This is a freeware * $Id: verification-code.php 2015-02-05 20:53:56 jingwhale$ *///設定字元集編碼header('Content-Type: text/html; charset=utf-8');?> verification code
顯示如下:
2)建立產生驗證碼頁面
建立codeimg.php為verification-code.php html代碼裡的img提供驗證碼圖片
首先必須在codeimg.php頁面開啟session;
其次,將我們封裝好的global.func.php全域函數庫引入進來;
最後,運行_code();
php /** * [verification-code] (C)2015-2100 jingwhale. * * This is a freeware * $Id: codeimg.php 2015-02-05 20:53:56 jingwhale$ *///開啟sessionsession_start();//引入全域函數庫(自訂)require dirname(__FILE__).'/includes/global.func.php';//運行驗證碼函數。通過資料庫的_code方法,設定驗證碼的各種屬性,產生圖片_code(125,25,6,false);?>
3)建立session檢驗機制
首先必須在verification-code.php頁面開啟session;
其次,設計提交驗證碼的方式,本文以get方式提交,當action=verification時提交成功;
最後,建立驗證函式,原理是將用戶端使用者提交的驗證碼同伺服器codeimg.php中session的驗證碼是否一致;這裡有一個js彈窗函數_alert_back(),我們也把它封裝在global.func.php裡;
修改verification-code.php中php代碼如下:
php /** * [verification-code] (C)2015-2100 jingwhale. * * This is a freeware * $Id: verification-code.php 2015-02-05 20:53:56 jingwhale$ *///設定字元集編碼header('Content-Type: text/html; charset=utf-8');//開啟sessionsession_start();//引入全域函數庫(自訂)require dirname(__FILE__).'/includes/global.func.php';//檢驗驗證碼if ($_GET['action'] == 'verification') { if (!($_POST['code'] == $_SESSION['code'])) { _alert_back('驗證碼不正確!'); }else{ _alert_back('驗證碼通過!'); }} ?> verification code
3.實現點擊驗證碼圖片更新驗證碼
上面若想實現驗證碼更新,必須重新整理頁面;我們寫一個codeimg.js函數實現點擊驗證碼圖片更新驗證碼
window.onload = function () { var code = document.getElementById('codeimg');//通過id找到html中img標籤 code.onclick = function () {//為標籤添加點擊事件 this.src='codeimg.php?tm='+Math.random();//修改時間,重新指向codeimg.php }; }
然後在verification-code.php html代碼head裡它即可。
完
歡迎轉載。轉載請註明轉載字樣,標註原作者和原博文地址。
以上就介紹了php實現動態隨機驗證碼機制(CAPTCHA),包括了方面的內容,希望對PHP教程有興趣的朋友有所協助。