create_sess_id()結合微秒時間與隨機數,經雙重 MD5 雜湊後截取指定長度(預設 32 字元,最小 16)。
function create_sess_id($len = 32) {
if (!is_numeric($len) || $len > 32 || $len < 16) return;
list($usec, $sec) = explode(' ', microtime());
$time = (float)$usec + (float)$sec;
$rand = rand(100000, 999999);
$rand = rand($rand, $time);
mt_srand($rand);
$rand = mt_rand();
$sess = md5(md5($time) . md5($rand));
return substr($sess, 0, $len);
}
create_check_code()直接從 Session ID 中截取片段(預設 4 字元,最大 6),轉大寫回傳。
function create_check_code($len = 4) {
if (!is_numeric($len) || $len > 6 || $len < 1) return;
return strtoupper(substr(create_sess_id(), 16, $len));
}
create_check_image()使用 GD 函式建立 65x22 px 圖片,灰底白字,加入 200 個隨機干擾像素。
function create_check_image($code) {
$im = imagecreate(65, 22);
$bg = imagecolorallocate($im, 200, 200, 200);
$fg = imagecolorallocate($im, 255, 255, 255);
imagefill($im, 68, 30, $bg);
imagestring($im, 5, 8, 3, $code, $fg);
for ($i = 0; $i < 200; $i++) {
$color = imagecolorallocate($im, rand(0,255), rand(0,255), rand(0,255));
imagesetpixel($im, rand()%70, rand()%30, $color);
}
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
}
<?php
// captcha.php —— 專門輸出驗證碼圖片
session_start();
require_once 'functions.php'; // 上述三個函數
$code = create_check_code(4);
$_SESSION['verify_code'] = $code;
create_check_image($code);
?>
<img src="captcha.php" alt="驗證碼" onclick="this.src='captcha.php?'+Math.random()">
<input name="captcha" placeholder="輸入圖片代碼">
<?php
session_start();
$imgW = 80; $imgH = 20;
$pixelNum = 200; $useLine = true; $pixelMode = 2;
function make_seed() {
list($usec, $sec) = explode(' ', microtime());
return (float)$sec + ((float)$usec * 100000);
}
mt_srand(make_seed());
$authNum = mt_rand(100, 99999);
$_SESSION['verifycode'] = $authNum;
header('Content-Type: image/png');
$im = imagecreatetruecolor($imgW, $imgH);
$bg = imagecolorallocate($im, mt_rand(250,255), mt_rand(250,255), mt_rand(250,255));
imagefill($im, 0, 0, $bg);
$wordInfo = []; $totalW = 0;
for ($i = 0; $i < strlen($authNum); $i++) {
$space = mt_rand(1,5);
$font = rand(3,5);
$top = (mt_rand(1,9)%2) ? 1 : 3;
$wordInfo[$i] = [
'char' => $authNum[$i],
'font' => $font,
'offset' => $top,
'width' => imagefontwidth($font) + $space,
'height' => imagefontheight($font),
'color' => imagecolorallocate($im, mt_rand(0,50), mt_rand(0,150), mt_rand(0,200))
];
$totalW += $wordInfo[$i]['width'];
if ($i === 0) $totalH = $wordInfo[$i]['height'];
}
$ox = floor(($imgW - $totalW)/2);
$oy = floor(($imgH - $totalH)/2);
$w = 0;
foreach ($wordInfo as $v) {
imagestring($im, $v['font'], $ox + $w, $v['offset'] + $oy, $v['char'], $v['color']);
$w += $v['width'];
}
// 干擾點
if ($pixelMode == 1) {
$c = imagecolorallocate($im, mt_rand(50,255), mt_rand(50,255), mt_rand(50,255));
for ($i=0;$i<$pixelNum;$i++) imagesetpixel($im, mt_rand()%$imgW, mt_rand()%$imgH, $c);
} elseif ($pixelMode == 2) {
for ($i=0;$i<=128;$i++) {
$c = imagecolorallocate($im, rand(0,255), rand(0,255), rand(0,255));
imagesetpixel($im, mt_rand(2,128), mt_rand(2,38), $c);
}
}
imagepng($im);
imagedestroy($im);
?>
session_start() 並比對 $_SESSION['verify_code'](大小写不敏感建議 strtoupper)。