天天看點

比較全面的php session驗證碼與防識别

驗證碼開發過程中的 3 個誤區:

1、  背景幹擾:幹擾線、幹擾點、幹擾圖,基本沒有,程式很容易通過高亮度調節去除掉。

2、  字元旋轉:破解機器人通過數次學習、旋轉之後,能夠得到 90% 以上的正确識别率,采用正常字型,能夠得到接近 100% 的識别。

3、  随機間距:基本沒用,采用提取高亮度之後,采用圖檔切割的方法,很容易就将随機間距消滅掉。

防止被破解:

1、  背景幹擾線盡量能夠幹擾到字元,采用和字元相同的顔色,能夠破壞高亮度反差色提取法對字元的學習。 qq有采用。

2、  矢量變形:想 google 、 ms 、 yahoo 都采用了這種變态的方法,這種将字元進行扭曲變形,基本上機器識别率為零,因為沒有相對應的固定形狀。 損失是使用者也不一定認得。需要驗證碼圖檔有一些大才行。

3、  字元粘連,可以破壞掉字元切割法分割字元, google 也有用到這個, qq 也有采用。

4、  中文驗證碼,中文驗證碼的識别難度比較大,但是現在逐漸的也慢慢被學習并且破解。(香港,台灣是用繁體)

5、  字元旋轉:需要和字元粘連在一起才能夠起作用,他們一起,驗證碼幾乎不具備機器破解可能性。 加随機背景圖檔、随機字型、稍微旋轉字母或數字,位置不固定,稍微扭曲

注意:下載下傳空心字型

字型.ttf的當$mode=7的該字型必須支援中文,否則出現亂碼。

在服務端做驗證時取session存儲的驗證字元與使用者送出的字元進行比較,相同則通過驗證。

比較全面的php session驗證碼與防識别

<?php  

/* 

* @date 2011-2-24 

* @author hudeyong926 

*/  

function getcode($length = 32, $mode = 0) {  

    switch ($mode) {  

        case '1' :  

            $str = '123456789';  

            break;  

        case '2' :  

            $str = 'abcdefghijklmnopqrstuvwxyz';  

        case '3' :  

        case '4' :  

            $str = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz';  

        case '5' :  

            $str = 'abcdefghijklmnpqrstuvwxyz123456789';  

        case '6' :  

            $str = 'abcdefghijklmnopqrstuvwxyz1234567890';  

        case '7' ://中文驗證碼  

        default :  

            $str = 'abcdefghijklmnpqrstuvwxyzabcdefghijkmnpqrstuvwxyz23456789';  

    }  

    $result = '';  

    for($i = 0; $i < $length; $i ++) {  

        if ($mode == 7) {  

            $str [$i] = chr ( mt_rand ( 176, 215 ) ) . chr ( mt_rand ( 161, 249 ) );  

            $str [$i] = iconv ( "gb2312", "utf-8", $str [$i] ); //imagettftext是utf-8的,是以先轉換下  

            $result .= $str [$i];  

        } else {  

            $l = strlen ( $str ) - 1;  

            $num = mt_rand ( 0, $l );  

            $result .= $str [$num];  

        }  

    return $result;  

}  

//建立驗證圖檔  

function createauthnumimg($randstr, $fontname, $imgw = 100, $imgh = 40) {  

    header ( "content-type: image/png" );  

    $image = imagecreate ( $imgw, $imgh );  

    $fontsize = 20;//字号  

    //$green = imagecolorallocate($image,0x6b,0xc1,0x46);  

    $gray = imagecolorallocate ( $image, 228, 228, 228 ); //灰色  

    $red  = imagecolorallocate ( $image, 255, 102, 204 );//粉色   

    $blue = imagecolorallocate($image,0x53,0x68,0xbd);  

    $colors = array($red, $gray, $blue);  

    $color_b = imagecolorallocate ( $image, 0, 0, 0 ); //黑色  

    for($i = 0; $i < 1000; $i ++) { //繪背景幹擾點  

        imagesetpixel ( $image, mt_rand ( 0, $imgw ), mt_rand ( 0, $imgh ), $colors[rand(0,count($colors)-1)]);  

    imagerectangle ( $image, 0, 0, $imgw - 1, $imgh - 1, $color_b );//繪制邊框  

    imagettftext ( $image, $fontsize, 5, 3, 25, $color_b, $fontname, $randstr);///将驗證字元繪入圖檔 字元旋轉      

    for($i=0; $i<2; $i++){ //繪背景幹擾線  

        imageline($image, mt_rand(0,5), mt_rand(6,18), mt_rand(65,$imgw), mt_rand(6,$imgh), $color_b);//一條幹擾線  

    }     

    imagepng ( $image );  

    imagedestroy ( $image );  

session_start ();  

$verifycode = getcode ( 5 );  

$_session ['verify_code'] = $verifycode ;  

createauthnumimg ( $verifycode, "font.ttf", 75, 30); //字型存放路徑,如果你沒有檔案就去c:\windows\fonts檔案中找一個吧。  

/** 問答模式 

$a=getcode(2,1);   

$b=getcode(1,1);   

$passport = $a."+".$b."=?";   

$verifycode = $a+$b;   

$_session ['verify_code'] = $verifycode ;   

createauthnumimg ( $passport, "font.ttf", 75, 30); 

?>  

中文占兩個字元長度,需要控制驗證碼圖檔的長度,一個中文位置相當于2個非中文

比較全面的php session驗證碼與防識别

<?php echo strlen('中'); echo strlen('ad');?>  

為了避免機器人的破解,驗證碼的視覺效果越來越差,随之很多網站就加了“看不清?請重新整理”之類的功能,當然也不是簡簡單單的頁面重新整理,是隻重新整理驗證碼部分,使用者進而得到一個新的驗證碼。在網上看了些别人寫的方法,下面總結兩種。

第一種比較簡單,運用一下onclick即可,直接點選驗證碼的圖檔就可以重新整理,不過最好在驗證碼後面說明一下,提示有這個功能。

比較全面的php session驗證碼與防識别

<img src="validimg.jsp" alt="看不清?請重新整理" width="50" height="20" onclick="this.src=this.src+'?'+math.random()" />  

比較全面的php session驗證碼與防識别

<img src="validimg.jsp" width="50" height="20" > <a href="javascript:reloadimage("validimg.jsp" );">重新整理</a>  

<script language="javascript">  

function reloadimage(url){  

document.formname.img1.src = url+math.random();  

</script>