驗證碼是防止機器人惡意提交表單的經典手段。本文詳細解析如何使用 PHP GD 庫繪製帶有「雪花」干擾背景的圖形驗證碼,涵蓋 Session 驗證流程、圖片生成邏輯、干擾元素繪製技巧與安全性考量。
test.php:顯示輸入框與驗證碼圖片,處理表單提交,比對 Session 中儲存的驗證碼。YanZhengMa.php:接收 act=init 參數,生成 PNG 圖片並輸出至瀏覽器,同時將驗證碼寫入 Session。<?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() |
$chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';(排除易混淆字元)。imageline() 繪製隨機直線/曲線,增加 OCR 識別難度。imagettftext() 載入 .ttf 字體,可實現旋轉、扭曲等進階效果。unset($_SESSION['login_check_number']),避免同一驗證碼被重複使用。--with-gd,且無輸出前空白字元(檢查 ?> 後是否有換行)。session_start(),且瀏覽器接受 Cookie。imagettftext() 搭配中文字體檔。本範例展示了 GD 庫繪製驗證碼的經典流程:建立畫布 → 繪製背景干擾 → 繪製目標文字 → 輸出圖片。理解此流程有助於客製化更強健的驗證機制,但現代專案建議優先採用成熟的第三方驗證服務,平衡開發成本與安全防護。