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

PHP 驗證碼類 Captcha:GD 繪製干擾線/像素/隨機字元完整實作

     編輯:PHP 綜合知識

類別功能

  • 生成 PNG 驗證碼圖片,含隨機字元、干擾線、干擾像素、多邊形背景。
  • 字元存入 Session,提供 check() 驗證方法。
  • 可配置長度、寬高、干擾數量、字體大小範圍。

核心代碼 (Captcha.class.php)

<?php
class Captcha {
    private $sname;

    public function __construct($sname = '') {
        $this->sname = $sname ?: 'm_captcha';
    }

    public function create($length = 4, array $param = []) {
        header('Content-Type: image/png');

        $code = $this->random($length);
        $this->captcha_session($this->sname, $code);

        $w = $param['width'] ?? 13;
        $h = $param['height'] ?? 18;
        $pnum = $param['pnum'] ?? 100;
        $lnum = $param['lnum'] ?? 2;

        $imgW = $w * $length + 10;
        $imgH = $h + 6;
        $im = imagecreate($imgW, $imgH);

        $bg = imagecolorallocate($im, 238, 238, 238);
        // 隨機多邊形背景
        $pts = [];
        for ($i=0;$i<12;$i++) $pts[] = mt_rand(0, $imgW);
        imagefilledpolygon($im, $pts, 6, imagecolorallocate($im, mt_rand(170,255), mt_rand(200,255), mt_rand(210,255)));

        // 繪製字元
        for ($i=0;$i<$length;$i++) {
            $color = imagecolorallocate($im, mt_rand(0,50), mt_rand(0,150), mt_rand(0,200));
            $x = $i/$length * $imgW + rand(1,6);
            $y = rand(1, $imgH/3);
            imagestring($im, mt_rand(4,6), $x, $y, $code[$i], $color);
        }

        // 干擾像素
        for ($i=0;$i<$pnum;$i++) {
            imagesetpixel($im, mt_rand(0,$imgW), mt_rand(0,$imgH), imagecolorallocate($im, mt_rand(0,255), mt_rand(0,255), mt_rand(0,255)));
        }
        // 干擾線
        for ($i=0;$i<$lnum;$i++) {
            imageline($im, mt_rand(0,$imgW), mt_rand(0,$imgH), mt_rand(0,$imgW), mt_rand(0,$imgH), imagecolorallocate($im, mt_rand(50,255), mt_rand(150,255), mt_rand(200,255)));
        }

        imagepng($im);
        imagedestroy($im);
    }

    public function check($input, $sname = '') {
        $sname = $sname ?: $this->sname;
        session_start();
        $stored = $_SESSION[$sname] ?? '';
        unset($_SESSION[$sname]); // 一次性驗證碼
        return strtoupper($input) === strtoupper($stored);
    }

    private function random($len) {
        $chars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ'; // 排除易混淆字元
        $str = '';
        for ($i=0;$i<$len;$i++) $str .= $chars[mt_rand(0, strlen($chars)-1)];
        return $str;
    }

    private function captcha_session($name, $value) {
        session_start();
        $_SESSION[$name] = $value;
    }
}

使用範例

顯示驗證碼 (captcha.php)

<?php
require 'Captcha.class.php';
$captcha = new Captcha();
$captcha->create(4, ['width'=>15, 'height'=>22, 'pnum'=>80, 'lnum'=>3]);

表單驗證

<form method="post">
    <img src="captcha.php" onclick="this.src='captcha.php?'+Math.random()" />
    <input name="captcha" required />
    <button type="submit">送出</button>
</form>

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $captcha = new Captcha();
    if ($captcha->check($_POST['captcha'])) {
        echo "驗證通過";
    } else {
        echo "驗證碼錯誤";
    }
}

安全性強化建議

  • 字元集去模糊:移除 0/O、1/I/l、8/B 等易混淆字元 (代碼已實作)。
  • Session 防固化:驗證後立即 unset,防止重放攻擊。
  • 限制嘗試次數:同 IP/Session 限制 5 次失敗後鎖定。
  • 現代替代:Google reCAPTCHA v3 (行為分析、無感驗證)、hCaptcha、Turnstile (Cloudflare)。
  • GD 限制:無法生成向量字體、抗鋸齒差,高安全需求建議用 imagettftext + TTF 字體或第三方服務。

結語

Captcha 類別以原生 GD 實現經典驗證碼功能,代碼精簡易懂,適合教學與低風險表單保護。生產環境面對自動化攻擊建議接入成熟驗證碼服務,兼顧安全性與用戶體驗。

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