關於部落格
說想說的,記想記的;

未完待續。
  • 87404

    累積人氣

  • 9

    今日人氣

    0

    追蹤人氣

利用 PHP 實作一個簡單的圖形文字驗證碼

產生文字圖檔的 php 程式,如 authimg.php


<?php
    // 檔案類型
    Header("Content-type: image/PNG");

    // 產生種子, 作圖形干擾用
    srand((double)microtime()*1000000);

    // 產生圖檔, 及定義顏色
    $im = imageCreate(70, 28);
    $back = ImageColorAllocate($im, 255, 255, 204);
    $font = ImageColorAllocate($im, 10, 10, 10);
    $point = ImageColorAllocate($im, 204, 0, 51);

    // 自己的密碼對照表與演算法
    include_once("admin_func.php");
    $authText = num2text($HTTP_GET_VARS['authnum']); // 轉換
   
    // 填入圖檔底色, 及寫入驗證文字至圖檔中
    imageFill($im, 0, 0, $back);
    imageString($im, 5, 10, 8, $authText, $font);

    // 插入圖形干擾點共 50 點, 可插入更多, 但可能會使圖形太過混雜
    for($i = 0; $i < 50; $i++) {
        imagesetpixel($im, rand() % 70 , rand() % 28 , $point);
    }

    // 定義圖檔類型並輸入, 最後刪除記憶體
    ImagePNG($im);
    ImageDestroy($im);
?>




密碼對照表 function num2text()



由於 Form 表單是用傳遞參數的方法呼叫 authimg.php,所以機器人程式可能會「猜」到你的驗證碼,所以我們使用一個密碼對照表,來轉換數字變成英文字後,再用這些英文字來產生圖形。


比方說,驗證碼為 12345,但轉換後的英文是 ASDFG,則機器人程式分析網頁時,會抓到參數是 12345,但肉眼看到要輸入 ASDFG 才正確,這樣可以避免「進階版」的機器人真的猜到驗證碼。至於密碼對照表要怎麼設計,就看個人了。


以下是一個簡單的範例,輸入是六個數字,先拿 1st 和 2nd 數字相加,轉成英文,再來 2nd 和 3th 數字相加,轉成英文,以此類推,最後會得到五個英文。


 function num2text($num) {
    $text = "";
   
    for ($i = 0; $i < strlen($num) - 1; $i++) {
        $shift = substr($num, $i, 1);
        $char = substr($num, $i + 1, 1);
        $key = $char + $shift;
       
        switch ($key) {
            case '0': $text .= "a"; break;
            case '1': $text .= "B"; break;
            case '2': $text .= "3"; break;
            case '3': $text .= "D"; break;
            case '4': $text .= "E"; break;
            case '5': $text .= "F"; break;
            case '6': $text .= "G"; break;
            case '7': $text .= "H"; break;
            case '8': $text .= "i"; break;
            case '9': $text .= "J"; break;
            case '10': $text .= "K"; break;
            case '11': $text .= "Z"; break;
            case '12': $text .= "7"; break;
            case '13': $text .= "N"; break;
            case '14': $text .= "4"; break;
            case '15': $text .= "5"; break;
            case '16': $text .= "Q"; break;
            case '17': $text .= "R"; break;
            case '18': $text .= "8"; break;
            case '19': $text .= "T"; break;
        }
    }
   
    return $text;
}


網站上的表單填寫


 <?php
    // 產生種子與驗證碼, 產生六位數字
    srand((double) microtime() * 1000000);
    while(($authnum = rand() % 1000000) < 100000);
?>

<form method="post" action="xxxx.php">

<!-- 把驗證碼傳給處理的 xxxx.php -->
<input type="hidden" name="authnum" value="<?php echo $authnum; ?>">

<!-- 呼叫產生圖形文字驗證碼的程式, 參數為 authnum, authimg.php 會依據密碼對照表與演算法產生與 authnum 完全不同的文字圖形 -->
<img src='authimg.php?authnum=<?php echo $authnum; ?>'>
<input type="text" name="authtext" class="file" size="6">



驗證所輸入的驗證碼


 <?php
    $authnum = $_POST["authnum"];
    $authtext = $_POST["authtext"];
   
    // 自己的密碼對照表與演算法
    include_once("admin_func.php");
    if ($authtext != num2text($authnum)) {
        blah blah...
    } else {
        // insert to database
    }
?>


相簿設定
標籤設定
相簿狀態