<?php
session_start();

class CaptchaGenerator {
    // 配置参数
    private $config = [
        'width' => 120,             // 图片宽度
        'height' => 40,            // 图片高度
        'charLength' => 5,         // 验证码长度
        'charSet' => '0123456789', // 字符集
        'fontSize' => 20,          // 字体大小
        'noiseDots' => 50,         // 噪点数量
        'noiseLines' => 3,         // 干扰线数量
        'sessionKey' => 'zengscode' // Session存储键
    ];

    private $image;
    private $code;

    public function __construct($customConfig = []) {
        $this->config = array_merge($this->config, $customConfig);
        
        if (isset($_GET['width']) && is_numeric($_GET['width'])) {
            $this->config['width'] = (int)$_GET['width'];
        }
        if (isset($_GET['height']) && is_numeric($_GET['height'])) {
            $this->config['height'] = (int)$_GET['height'];
        }
    }

    private function generateCode() {
        $chars = str_split($this->config['charSet']);
        $this->code = '';
        for ($i = 0; $i < $this->config['charLength']; $i++) {
            $this->code .= $chars[array_rand($chars)];
        }
        $_SESSION[$this->config['sessionKey']] = $this->code;
    }

    private function createImage() {
        $this->image = imagecreatetruecolor($this->config['width'], $this->config['height']);
        $bgColor = imagecolorallocate($this->image, 255, 255, 255);
        imagefill($this->image, 0, 0, $bgColor);
    }

    private function addCharacters() {
        $charSpacing = $this->config['width'] / ($this->config['charLength'] + 1);
        
        // 调整垂直基线,使文字居中且完整显示
        $baseY = $this->config['height'] - ($this->config['fontSize'] / 2); // 从底部开始计算
        
        for ($i = 0; $i < strlen($this->code); $i++) {
            $textColor = imagecolorallocate($this->image, 
                rand(0, 150), rand(0, 150), rand(0, 150)
            );
            
            $angle = rand(-20, 20);
            
            // 水平位置
            $x = ($i + 1) * $charSpacing - ($this->config['fontSize'] / 2) + rand(-5, 5);
            // 垂直位置调整,确保文字完整显示并居中
            $y = $baseY + rand(-5, 5);
            
            // 使用内置字体5,位置从左下角计算
            imagestring($this->image, 5, $x, $y - $this->config['fontSize'], $this->code[$i], $textColor);
        }
    }

    private function addNoiseDots() {
        for ($i = 0; $i < $this->config['noiseDots']; $i++) {
            $color = imagecolorallocate($this->image, 
                rand(0, 255), rand(0, 255), rand(0, 255)
            );
            imagesetpixel($this->image, 
                rand(0, $this->config['width']), 
                rand(0, $this->config['height']), 
                $color
            );
        }
    }

    private function addNoiseLines() {
        for ($i = 0; $i < $this->config['noiseLines']; $i++) {
            $color = imagecolorallocate($this->image, 
                rand(0, 255), rand(0, 255), rand(0, 255)
            );
            imageline($this->image, 
                rand(0, $this->config['width']), rand(0, $this->config['height']),
                rand(0, $this->config['width']), rand(0, $this->config['height']),
                $color
            );
        }
    }

    public function generate() {
        $this->generateCode();
        $this->createImage();
        $this->addCharacters();
        $this->addNoiseDots();
        $this->addNoiseLines();
        
        header('Content-Type: image/png');
        imagepng($this->image);
        imagedestroy($this->image);
    }

    public function getCode() {
        return $this->code;
    }

    public static function verify($input, $sessionKey = 'captcha_code') {
        return isset($_SESSION[$sessionKey]) && 
               strtolower($input) === strtolower($_SESSION[$sessionKey]);
    }
}

// 使用示例
$captcha = new CaptchaGenerator();
$captcha->generate();
?>