# 如何用PHP实现数字验证码 ## 引言 在当今互联网应用中,验证码(CAPTCHA)是保护网站免受自动化程序攻击的重要手段。数字验证码作为最常见的形式之一,通过要求用户识别并输入随机生成的数字组合来区分人类用户和机器人。本文将详细介绍如何使用PHP实现一个完整的数字验证码系统。 ## 一、验证码的基本原理 ### 1.1 验证码的作用 - 防止暴力破解:阻挡自动化登录尝试 - 防止垃圾注册:阻止机器人批量注册账号 - 保护数据安全:限制自动化数据抓取 ### 1.2 数字验证码的特点 - 实现简单 - 用户识别难度适中 - 可自定义复杂度 ## 二、基础实现步骤 ### 2.1 创建画布 ```php <?php // 创建画布 $width = 120; $height = 40; $image = imagecreatetruecolor($width, $height); // 设置背景色(白色) $bgColor = imagecolorallocate($image, 255, 255, 255); imagefill($image, 0, 0, $bgColor); // 生成4位随机数字 $code = ''; for ($i = 0; $i < 4; $i++) { $code .= rand(0, 9); } // 将验证码存入session session_start(); $_SESSION['captcha'] = $code; // 设置文字颜色(黑色) $textColor = imagecolorallocate($image, 0, 0, 0); // 绘制文字 for ($i = 0; $i < strlen($code); $i++) { $fontSize = 20; $x = ($i * 30) + 10; $y = 30; imagestring($image, $fontSize, $x, $y, $code[$i], $textColor); } // 添加干扰点 for ($i = 0; $i < 200; $i++) { $pixelColor = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(0, 255)); imagesetpixel($image, rand(0, $width), rand(0, $height), $pixelColor); } // 添加干扰线 for ($i = 0; $i < 5; $i++) { $lineColor = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(0, 255)); imageline($image, rand(0, $width), rand(0, $height), rand(0, $width), rand(0, $height), $lineColor); } // 设置响应头 header('Content-Type: image/png'); // 输出图像 imagepng($image); // 释放资源 imagedestroy($image); 将上述步骤整合为完整文件 captcha.php:
<?php session_start(); // 创建画布 $width = 120; $height = 40; $image = imagecreatetruecolor($width, $height); // 设置背景色 $bgColor = imagecolorallocate($image, 255, 255, 255); imagefill($image, 0, 0, $bgColor); // 生成随机验证码 $code = ''; for ($i = 0; $i < 4; $i++) { $code .= rand(0, 9); } $_SESSION['captcha'] = $code; // 绘制文字 $textColor = imagecolorallocate($image, 0, 0, 0); for ($i = 0; $i < strlen($code); $i++) { $fontSize = 20; $x = ($i * 30) + 10; $y = 30; imagestring($image, $fontSize, $x, $y, $code[$i], $textColor); } // 添加干扰 for ($i = 0; $i < 200; $i++) { $pixelColor = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(0, 255)); imagesetpixel($image, rand(0, $width), rand(0, $height), $pixelColor); } for ($i = 0; $i < 5; $i++) { $lineColor = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(0, 255)); imageline($image, rand(0, $width), rand(0, $height), rand(0, $width), rand(0, $height), $lineColor); } // 输出图像 header('Content-Type: image/png'); imagepng($image); imagedestroy($image); <img src="captcha.php" id="captcha" onclick="refreshCaptcha()"> <input type="text" name="captcha" placeholder="请输入验证码"> <button onclick="refreshCaptcha()">刷新验证码</button> <script> function refreshCaptcha() { document.getElementById('captcha').src = 'captcha.php?' + Math.random(); } </script> <?php session_start(); if ($_SERVER['REQUEST_METHOD'] === 'POST') { $userInput = $_POST['captcha'] ?? ''; $captcha = $_SESSION['captcha'] ?? ''; if (empty($userInput) || $userInput !== $captcha) { die('验证码错误'); } // 验证通过后的逻辑 echo '验证成功'; } // 加载字体文件 $fontFile = 'arial.ttf'; // 绘制每个字符 for ($i = 0; $i < strlen($code); $i++) { $angle = rand(-10, 10); $x = ($i * 30) + 10; $y = 30; imagettftext($image, 20, $angle, $x, $y, $textColor, $fontFile, $code[$i]); } // 创建扭曲函数 function distortImage($image) { $width = imagesx($image); $height = imagesy($image); $newImage = imagecreatetruecolor($width, $height); for ($x = 0; $x < $width; $x++) { for ($y = 0; $y < $height; $y++) { $newX = $x + sin($y / 10) * 3; $newY = $y; if ($newX >= 0 && $newX < $width && $newY >= 0 && $newY < $height) { $color = imagecolorat($image, $newX, $newY); imagesetpixel($newImage, $x, $y, $color); } } } return $newImage; } // 应用扭曲效果 $image = distortImage($image); // 为每个字符设置不同颜色 for ($i = 0; $i < strlen($code); $i++) { $charColor = imagecolorallocate($image, rand(50, 200), rand(50, 200), rand(50, 200)); imagettftext($image, 20, $angle, $x, $y, $charColor, $fontFile, $code[$i]); } 通过本文的介绍,我们了解了如何使用PHP从零开始实现数字验证码功能,并探讨了多种优化方案和安全注意事项。验证码作为基础安全措施,在实际开发中应根据项目需求选择合适的实现方式。随着技术的发展,更先进的验证方式不断涌现,但理解基础原理仍是应对各种安全挑战的根本。
注意:本文示例代码已简化,实际应用中请根据需求添加更多安全措施和错误处理。 “`
(全文约3050字,包含代码示例和技术说明)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。