<?php
// 1. 設定 Session 儲存路徑(需可讀寫)
$sessPath = dirname(__FILE__) . '/../data/sessions/';
if (is_writable($sessPath) && is_readable($sessPath)) {
session_save_path($sessPath);
}
session_start();
class Captcha {
private $im;
public function generate() {
// 5 秒內不重新生成
$now = time();
if (empty($_SESSION['verifycode']) || empty($_SESSION['verifycode_last']) ||
$now - $_SESSION['verifycode_last'] > 5) {
$code = '';
for ($i=0;$i<4;$i++) $code .= chr(mt_rand(65,90)); // A-Z
$_SESSION['verifycode'] = strtolower($code);
$_SESSION['verifycode_last'] = $now;
}
$code = $_SESSION['verifycode'];
$len = strlen($code);
// 建立畫布
$this->im = imagecreate(50, 20);
imagecolorallocate($this->im, 255,255,255); // 白底(第一個顏色為背景)
$line1 = imagecolorallocate($this->im, 240,220,180);
$line2 = imagecolorallocate($this->im, 250,250,170);
// 橫向干擾線
for ($y=3;$y<=16;$y+=3) imageline($this->im, 2,$y, 48,$y, $line1);
// 斜向干擾線
for ($x=2;$x<52;$x+=mt_rand(3,6)) imageline($this->im, $x,2, $x-6,18, $line2);
// 邊框
$border = imagecolorallocate($this->im, 0x99,0x99,0x99);
imagerectangle($this->im, 0,0, 49,19, $border);
// 文字
$fontColor = imagecolorallocate($this->im, 48,61,50);
for ($i=0;$i<$len;$i++) {
$ch = strtoupper($code[$i]);
imagestring($this->im, 5, $i*10+6, mt_rand(2,4), $ch, $fontColor);
}
// 輸出
header("Pragma: no-cache");
header("Cache-Control: no-cache");
header("Expires: 0");
if (function_exists('imagejpeg')) {
header("Content-Type: image/jpeg");
imagejpeg($this->im);
} else {
header("Content-Type: image/png");
imagepng($this->im);
}
imagedestroy($this->im);
exit;
}
}
// 直接輸出
(new Captcha())->generate();
?>
<?php
// 替換 imagecreate → imagecreatetruecolor
// 替換 imagestring → imagettftext
$im = imagecreatetruecolor(100, 35);
$font = __DIR__.'/fonts/arial.ttf';
for ($i=0;$i<4;$i++) {
$color = imagecolorallocate($im, mt_rand(0,100), mt_rand(0,100), mt_rand(0,100));
imagettftext($im, 20, mt_rand(-15,15), $i*22+10, 25, $color, $font, $code[$i]);
}
?>