当前位置: 首页 > 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.jsqmd.com/news/947324/

相关文章:

  • 从收藏吃灰到高效执行:2026年度高内聚代码灵感仓储工具深度解析
  • 第七章:自定义命令、规则与上下文
  • 别慌!网站突然打不开显示Error 522?手把手教你排查百度云加速与源站的连接问题
  • DeepSeek V4实测:百万上下文与MoE架构如何重构AI成本模型
  • 量子退火在最小顶点多割问题中的应用与优化
  • 仓储软件(WMS)值得推荐的选择方向 - 品牌排行榜
  • 第八章:工具、权限与 MCP 扩展
  • 用超声波传感器与Arduino制作自由形态电子秤:从测距到称重的跨界实践
  • 如何快速定位手机号码归属地:三步完成精准查询
  • AI工具链×秒杀核心链路深度耦合实践(阿里/拼多多/得物三巨头架构师联合复盘版)
  • PHP图数据结构与算法实现
  • 工单响应时效从47分钟压缩至92秒,这3个AI集成节点你绝对漏掉了
  • 利用快马平台快速构建potplayer字幕翻译工具原型
  • 百度网盘限速终结者:3分钟搞定高速下载的终极方案
  • 合规红线下的智能外呼:如何用RAG+本地化语音模型通过银保监AI外呼备案(附过审配置清单)
  • 伺服驱动器方向反转排查与设置
  • Gemma 4 9B:面向开发者的轻量级AI生产力引擎
  • 动态多重网络层间差异检验:谱嵌入与Bootstrap方法
  • OpenCode 教程目录
  • Determined:一个集成的深度学习训练平台
  • 计算机重装系统出现SYSTEM磁盘?
  • 量子上三角矩阵代数UTq(n)的构造与Hopf结构解析
  • 高端音频旋转电位器怎么选?ALPS RK14J11R000H VS TONEVEE TV14 参数PK
  • 公平k中心聚类算法:原理、优化与应用
  • 基于深度学习的文本自动摘要系统
  • 推荐一个适合维保公司的报修系统,支持多报修单位独立管理
  • 第十章:最佳实践、完整配置模板与排障
  • 手机信号满格却上不了网?一文搞懂LTE/5G的PLMN选网与漫游机制
  • PHP域名解析与CDN加速技术
  • 告别选型内耗,大模型API 采购中转成为企业 AI 降本增效新支点