应换用imagettftext+真字体、控制旋转±15度、设置高对比色、添加避开文字的干扰线,并使用去歧义字符集如'23456789ABCDEFGHJKLMNPQRSTUVWXYZ'。

PHP验证码图片里文字太糊、难识别怎么办
默认的 imagestring 或 GD 库简单绘图生成的验证码,常因字体小、无干扰线、颜色对比弱导致 OCR 易识别或人眼难辨。这不是“规则没改对”,而是生成逻辑本身缺乏抗识别设计。
- 优先换用
imagettftext+ 真字体文件(如simhei.ttf),避免位图字体锯齿 - 文字旋转角度控制在
-15到15度之间,过大反而降低人工可读性 - 背景色与字色必须有足够色差,例如用
imagecolorallocate($im, 240, 240, 240)做浅灰底,再用imagecolorallocate($im, 40, 40, 40)写深灰字 - 加 2–3 条随机位置的
imageline干扰线,但避开文字主区域(可用mt_rand(10, $width-10)控制起始点)
验证码字符集被绕过:如何禁用易混淆字符
默认用 0123456789abcdefghijklmnopqrstuvwxyz 会引入 o/0、l/1、i/1 等视觉歧义组合,攻击者写脚本时直接剔除这些字符就能提升识别率。
- 显式定义安全字符集,例如:
$chars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';(去掉 0,O,1,I,L等) - 长度建议固定为 4 或 5,太短易暴力,太长用户输入意愿下降
- 生成后立即存入
$_SESSION['captcha_code'],且调用后立刻unset($_SESSION['captcha_code'])防重放
GD 扩展关闭了,还能生成验证码吗
不能用 imagecreate 系列函数,但不等于没法做。替代方案是转向纯文本+CSS 渲染,或使用外部服务接口,不过前者安全性极低,后者增加依赖。
- 检查是否真没开 GD:运行
phpinfo()搜索gd,确认GD Support为enabled - 若服务器不允许启用 GD,可改用
imagick扩展(需安装 ImageMagick),对应函数如new ImagickDraw()、annotateImage() - 不推荐用 base64 编码字符串拼接 SVG 的“伪图形”方案——现代 OCR 对 SVG 文字提取毫无压力
验证码校验总失败?session 和编码容易漏掉
最常见不是规则写错,而是前后端环境不一致:PHP session 未启动、字符大小写未统一、空格未 trim、或多字节字符(如中文验证码)引发编码截断。
立即学习“PHP免费学习笔记(深入)”;
- 生成验证码前必须有
session_start(),且不能有任何输出(包括 BOM、空行、echo) - 校验时用
strtolower(trim($_POST['captcha'])) === strtolower($_SESSION['captcha_code']),强制忽略大小写和首尾空格 - 若用中文字符,确保 PHP 文件保存为 UTF-8 无 BOM,且
header('Content-Type: text/html; charset=utf-8')已设置 - 验证码有效期建议设为 300 秒,用
$_SESSION['captcha_time'] = time()记录生成时间,校验时比对











