首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP GD 庫實作雪花干擾驗證碼完整教學

     編輯:PHP 相關知識

驗證碼是防止機器人惡意提交表單的經典手段。本文詳細解析如何使用 PHP GD 庫繪製帶有「雪花」干擾背景的圖形驗證碼,涵蓋 Session 驗證流程、圖片生成邏輯、干擾元素繪製技巧與安全性考量。

整體架構:兩支程式協作

  1. 主程式 test.php:顯示輸入框與驗證碼圖片,處理表單提交,比對 Session 中儲存的驗證碼。
  2. 圖片生成器 YanZhengMa.php:接收 act=init 參數,生成 PNG 圖片並輸出至瀏覽器,同時將驗證碼寫入 Session。

核心程式碼:YanZhengMa.php 逐段解析

<?php
session_start();
session_register("login_check_number"); // PHP 5.4+ 已移除,建議直接用 $_SESSION

$img_height = 120;  // 圖片寬度(像素)
$img_width  = 40;   // 圖片高度(像素)

if ($_GET['act'] === 'init') {
    // 1. 產生 4 位 16 進位隨機碼 (0-9, a-f)
    $nmsg = '';
    for ($i = 0; $i < 4; $i++) {
        $nmsg .= dechex(rand(0, 15));
    }
    $_SESSION['login_check_number'] = $nmsg; // 存入 Session

    // 2. 建立畫布
    $aimg = imagecreate($img_height, $img_width);
    $white = imagecolorallocate($aimg, 255, 255, 255); // 第一次配色即為背景色
    $black = imagecolorallocate($aimg, 0, 0, 0);
    imagerectangle($aimg, 0, 0, $img_height-1, $img_width-1, $black); // 邊框

    // 3. 繪製「雪花」干擾背景:100 個隨機位置、顏色、大小的 * 號
    for ($i = 1; $i <= 100; $i++) {
        $color = imagecolorallocate($aimg, 
            mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255)); // 淺色系
        imagestring($aimg, 1, 
            mt_rand(1, $img_height), mt_rand(1, $img_width), 
            "*", $color);
    }

    // 4. 繪製驗證碼字元:逐字隨機字體大小(3-5)、位置、深色系顏色
    for ($i = 0; $i < strlen($_SESSION['login_check_number']); $i++) {
        $char = $_SESSION['login_check_number'][$i];
        $color = imagecolorallocate($aimg, 
            mt_rand(0, 100), mt_rand(0, 150), mt_rand(0, 200)); // 深色系,與背景區隔
        imagestring($aimg, mt_rand(3, 5),
            $i * $img_height / 4 + mt_rand(1, 10), 
            mt_rand(1, $img_width / 2), 
            $char, $color);
    }

    // 5. 輸出圖片
    header("Content-Type: image/png");
    imagepng($aimg);
    imagedestroy($aimg); // 釋放記憶體
}
?>

關鍵技術細節

技術點說明
顏色區隔策略背景干擾用 RGB 200-255(淺色),驗證碼用 RGB 0-200(深色),視覺上易於分辨
隨機性來源使用 mt_rand() 而非 rand(),速度更快、隨機度更好
字體大小變化imagestring() 參數 3-5 對應內建字體大小,模擬手寫不規則感
Session 儲存驗證碼存於 $_SESSION['login_check_number'],主程式比對時需 session_start()

安全性增強建議

  • 擴大字元集:原版僅用 16 進位 (0-9, a-f),建議擴充至英數字混合:$chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';(排除易混淆字元)。
  • 加入干擾線條:使用 imageline() 繪製隨機直線/曲線,增加 OCR 識別難度。
  • 使用 TrueType 字體:改用 imagettftext() 載入 .ttf 字體,可實現旋轉、扭曲等進階效果。
  • 防重放攻擊:驗證成功後立即 unset($_SESSION['login_check_number']),避免同一驗證碼被重複使用。
  • 現代替代方案:考慮 Google reCAPTCHA v3、hCaptcha 或行為分析型驗證,兼顧安全性與使用者體驗。

常見問題排查

  • 圖片顯示破圖:確認 PHP 已編譯 --with-gd,且無輸出前空白字元(檢查 ?> 後是否有換行)。
  • Session 失效:確認兩支程式均在最開頭呼叫 session_start(),且瀏覽器接受 Cookie。
  • 中文亂碼:若需顯示中文驗證碼,必須使用 imagettftext() 搭配中文字體檔。

總結

本範例展示了 GD 庫繪製驗證碼的經典流程:建立畫布 → 繪製背景干擾 → 繪製目標文字 → 輸出圖片。理解此流程有助於客製化更強健的驗證機制,但現代專案建議優先採用成熟的第三方驗證服務,平衡開發成本與安全防護。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved