当前位置: 首页 > news >正文

PHP图形验证码技术实现

PHP图形验证码与验证码技术实现

验证码是防止自动化攻击的常用手段。从简单的数字验证码到行为验证,PHP都能实现。今天说说各种验证码的实现方式。

用GD库生成图片验证码是最传统的方式。核心思路是生成随机字符,画到图片上,添加干扰线和噪点来增加识别难度。

```php
class CaptchaGenerator
{
private int $width;
private int $height;
private int $length;

public function __construct(int $width = 150, int $height = 50, int $length = 4)
{
$this->width = $width;
$this->height = $height;
$this->length = $length;
}

public function generate(): array
{
$image = imagecreatetruecolor($this->width, $this->height);

// 背景色
$bgColor = imagecolorallocate($image, 255, 255, 255);
imagefill($image, 0, 0, $bgColor);

// 干扰线
for ($i = 0; $i < 5; $i++) {
$color = imagecolorallocate($image, rand(150, 200), rand(150, 200), rand(150, 200));
imageline($image, rand(0, $this->width), rand(0, $this->height), rand(0, $this->width), rand(0, $this->height), $color);
}

// 干扰点
for ($i = 0; $i < 100; $i++) {
$color = imagecolorallocate($image, rand(100, 200), rand(100, 200), rand(100, 200));
imagesetpixel($image, rand(0, $this->width), rand(0, $this->height), $color);
}

// 验证码字符
$chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
$code = '';

for ($i = 0; $i < $this->length; $i++) {
$char = $chars[rand(0, strlen($chars) - 1)];
$code .= $char;

$textColor = imagecolorallocate($image, rand(0, 80), rand(0, 80), rand(0, 80));
$x = 20 + $i * 30 + rand(-3, 3);
$y = rand(15, 35);
$angle = rand(-20, 20);

imagestring($image, 5, $x, $y, $char, $textColor);
}

// 输出图片到内存
ob_start();
imagepng($image);
$imageData = ob_get_clean();
imagedestroy($image);

return [
'code' => $code,
'image' => base64_encode($imageData),
'mime' => 'image/png',
];
}
}

$generator = new CaptchaGenerator();
$captcha = $generator->generate();
echo "验证码: {$captcha['code']}\n";
echo "

\n";
?>
```

数学验证码比字符验证码更友好,用户只需要计算结果:

```php
class MathCaptcha
{
public function generate(): array
{
$a = rand(1, 50);
$b = rand(1, 30);
$operators = ['+', '-'];
$op = $operators[array_rand($operators)];

$expression = "$a $op $b";
$result = $op === '+' ? $a + $b : $a - $b;

$image = imagecreatetruecolor(150, 50);
$bgColor = imagecolorallocate($image, 245, 245, 245);
imagefill($image, 0, 0, $bgColor);

for ($i = 0; $i < 3; $i++) {
$lineColor = imagecolorallocate($image, rand(180, 220), rand(180, 220), rand(180, 220));
imageline($image, rand(0, 150), rand(0, 50), rand(0, 150), rand(0, 50), $lineColor);
}

$textColor = imagecolorallocate($image, 50, 50, 50);
$font = 5;
$textX = 30;
$textY = 18;

// 逐字符绘制
for ($i = 0; $i < strlen($expression); $i++) {
$charColors = [imagecolorallocate($image, rand(30, 100), rand(30, 100), rand(30, 100))];
imagestring($image, $font, $textX + $i * 20, $textY + rand(-3, 3), $expression[$i], $charColors[0]);
}

ob_start();
imagepng($image);
$imageData = ob_get_clean();
imagedestroy($image);

return [
'expression' => $expression,
'result' => $result,
'image' => base64_encode($imageData),
];
}
}

$math = new MathCaptcha();
$captcha = $math->generate();
echo "计算: {$captcha['expression']} = ?\n";
echo "结果: {$captcha['result']}\n";
?>
```

验证码的验证逻辑也很重要,需要防止重复使用和超时。

```php
class CaptchaValidator
{
private Redis $redis;
private int $ttl;

public function __construct(Redis $redis, int $ttl = 300)
{
$this->redis = $redis;
$this->ttl = $ttl;
}

public function store(string $key, string $code): void
{
$this->redis->setex("captcha:$key", $this->ttl, $code);
}

public function validate(string $key, string $input): bool
{
$stored = $this->redis->get("captcha:$key");
if ($stored === false) {
return false; // 过期或不存在
}

// 验证后立即删除,防止重复使用
$this->redis->del("captcha:$key");

return strtoupper($stored) === strtoupper($input);
}

public function delete(string $key): void
{
$this->redis->del("captcha:$key");
}
}
?>
```

验证码是用户体验和安全性的平衡。太复杂了用户看不清,太简单了又防不住自动化攻击。实际项目中还可以考虑Google reCAPTCHA、滑动验证、点选验证等方式,这些通常比纯图形验证码的用户体验更好,安全性也更高。

http://www.rkmt.cn/news/1458835.html

相关文章:

  • 第八章:工具、权限与 MCP 扩展
  • AI工具链×秒杀核心链路深度耦合实践(阿里/拼多多/得物三巨头架构师联合复盘版)
  • 伺服驱动器方向反转排查与设置
  • 高端音频旋转电位器怎么选?ALPS RK14J11R000H VS TONEVEE TV14 参数PK
  • 告别选型内耗,大模型API 采购中转成为企业 AI 降本增效新支点
  • 手机信号满格却上不了网?一文搞懂LTE/5G的PLMN选网与漫游机制
  • Gemma-2本地部署实战:手机电脑跑通2B大模型全指南
  • 2026年留学生降AI指南:实测3款结构级优化工具,英文论文轻松过Turnitin检测 - 降AI实验室
  • ARKFCM algorithm
  • 2026年北京工伤律师推荐:5位专业实力派精选 - 本地品牌推荐
  • Gemma 4B本地部署实战:轻量大模型在Mac与树莓派上的高效运行
  • 0.005mm同轴度,圆樽底模轴的车削精度怎么保证
  • 百度网盘全速下载终极指南:告别限速,轻松获取真实下载链接
  • QMCFLAC2MP3终极指南:一键解锁QQ音乐格式限制
  • 手把手解析BQ4050的SMBus数据:如何从原始字节算出真实的电压、电流和电量百分比?
  • 列表List的语法
  • 第四章:配置体系详解与优先级
  • 深耕本土,精准赋能 —— 徐允雯以专业商事服务助力苏州创业生态建设
  • Qwen3.6-Plus深度适配嵌入式开发:国产编程模型实战指南
  • 告别盲调!用海德汉PWM21深度解析Endat信号:从位置值、报警到信号质量百分比
  • Dreamweaver CS6里的‘层’到底怎么用?手把手教你用AP Div搞定网页布局(附实战案例)
  • 蜘蛛池技术解析:原理、作用与作用点评——专业视角下的网站录入
  • ECU标定工程师避坑指南:用ASAP2 Studio更新A2L时,这3个细节决定成败
  • 自指螺旋拓扑——认知物理学大一统几何架构研究(世毫九实验室基础理论重大原创交叉课题)
  • 从“亚太2R”到“星链”:卫星天线角度计算的原理、变迁与自动化未来
  • 利用快马平台快速构建han1me动漫社区应用原型,验证核心功能
  • MATLAB手写霍夫曼编码函数(无工具箱依赖,含建树与编码效率分析)
  • 咸阳市2026年最新黄金回收白银回收铂金回收门店排行榜及联系方式电话推荐 - 盛世金银回收
  • Albion Online Statistics Analysis:从游戏数据到战略优势的完整指南
  • 湘潭市2026年最新黄金回收白银回收铂金回收门店排行榜及联系方式电话推荐 - 盛世金银回收