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

PHP 雪花背景驗證碼實作:Session 驗證與干擾字元繪製

     編輯:PHP 相關知識

特色

  • 背景以隨機顏色的 * 字元模擬「雪花」干擾。
  • 驗證碼為 4 位十六進位字元(0-9, a-f),存入 Session 驗證。
  • 使用 imageString() 內建字體繪製,無需外部 TTF 檔案。

驗證碼產生器 YanZhengMa.php

<?php
session_start();

// 參數
$imgH = 120; // 寬
$imgW = 40;  // 高

if (($_GET['act'] ?? '') === 'init') {
    // 產生 4 位十六進位隨機碼
    $code = '';
    for ($i = 0; $i < 4; $i++) {
        $code .= dechex(random_int(0, 15));
    }
    $_SESSION['login_check_number'] = $code;

    // 建立畫布
    $im = imagecreate($imgH, $imgW);
    $white = imagecolorallocate($im, 255, 255, 255); // 第一次配色視為背景
    $black = imagecolorallocate($im, 0, 0, 0);
    imagerectangle($im, 0, 0, $imgH - 1, $imgW - 1, $black); // 邊框

    // 繪製 100 個雪花(*),顏色較淡 (200-255)
    for ($i = 0; $i < 100; $i++) {
        $color = imagecolorallocate($im,
            random_int(200, 255),
            random_int(200, 255),
            random_int(200, 255)
        );
        imagestring($im, 1,
            random_int(1, $imgH),
            random_int(1, $imgW),
            '*', $color
        );
    }

    // 繪製驗證碼字元,顏色較深 (0-200),位置隨機偏移
    for ($i = 0; $i < 4; $i++) {
        $color = imagecolorallocate($im,
            random_int(0, 100),
            random_int(0, 150),
            random_int(0, 200)
        );
        imagestring($im,
            random_int(3, 5), // 字體大小 3-5
            $i * $imgH / 4 + random_int(1, 10), // X 平均分佈 + 隨機
            random_int(1, $imgW / 2),           // Y 上半部隨機
            $code[$i],
            $color
        );
    }

    header('Content-Type: image/png');
    imagepng($im);
    imagedestroy($im);
}
?>

驗證測試頁 test.php

<?php
session_start();
?>
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>雪花驗證碼測試</title></head><body>
<h2>雪花驗證碼測試</h2>
<form method="post">
    輸入驗證碼:<input type="text" name="number" maxlength="4" required>
    <img src="YanZhengMa.php?act=init" alt="驗證碼" onclick="this.src='YanZhengMa.php?act=init&'+Date.now()" style="cursor:pointer;vertical-align:middle">
    <br><button type="submit" name="sub">送出驗證</button>
</form>

<?php
if (isset($_POST['sub'])) {
    $input = strtolower(trim($_POST['number'] ?? ''));
    $sess = strtolower($_SESSION['login_check_number'] ?? '');
    if ($input === '' || $input !== $sess) {
        echo '<p style="color:red">驗證碼錯誤!</p>';
    } else {
        echo '<p style="color:green">驗證通過!</p>';
    }
}
?>
<hr>
<h3>原始碼檢視</h3>
<?php highlight_file('test.php'); ?>
<h3>驗證碼產生器原始碼</h3>
<?php highlight_file('YanZhengMa.php'); ?>
</body></html>

改進方向

  1. 增加字元集:將 dechex(random_int(0,15)) 改為從英數字元池抽取,提高組合數。
  2. 使用 TTF 字體:改用 imagettftext() 可獲得更美觀、難以 OCR 辨識的字型。
  3. 加入干擾線/曲線:使用 imageline()、imagearc() 增加干擾。
  4. Session 安全:驗證成功後立即 unset($_SESSION['login_check_number']) 防止重放。
  5. 現代替代:生產環境建議直接整合 reCAPTCHA v3 或 hCaptcha,無需自行維護圖形驗證碼。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved