目录

php版验证码图像转ASCII艺术形式验证码

目录

php版验证码图像转ASCII艺术形式验证码

https://i-blog.csdnimg.cn/direct/8ecc52a4f4ee475582b1d886261d6e22.png


<?php
session_start();
class AsciiCaptcha {
private $width = 180;
private $height = 50;
private $code;
private $image;
private $asciiChars = ['@', '#', '8', '&', 'o', ':', '*', '.', ' '];
public function __construct() {
$this->generateCode();
$this->createImage();
$this->addNoise();
$this->addText();
}
// 生成随机验证码
private function generateCode() {
$chars = '3456789ABCDEFGHJKLMNPQRSTUVWXYZ';
$this->code = substr(str_shuffle($chars), 0, 5);
$_SESSION['captcha_code'] = $this->code;
}
// 创建画布
private function createImage() {
$this->image = imagecreatetruecolor($this->width, $this->height);
$bgColor = imagecolorallocate($this->image, 240, 240, 240);
imagefill($this->image, 0, 0, $bgColor);
}
// 添加干扰元素
private function addNoise() {
// 添加随机点
for ($i = 0; $i < 200; $i++) {
$color = imagecolorallocate($this->image, rand(150, 220), rand(150, 220), rand(150, 220));
imagesetpixel($this->image, rand(0, $this->width), rand(0, $this->height), $color);
}
// 添加随机线条 - 粗细不一
for ($i = 0; $i < 8; $i++) {
$color = imagecolorallocate($this->image, rand(150, 200), rand(150, 200), rand(150, 200));
$thickness = rand(1, 3);
imagesetthickness($this->image, $thickness);
imageline(
$this->image,
rand(0, $this->width),
rand(0, $this->height),
rand(0, $this->width),
rand(0, $this->height),
$color
);
}
imagesetthickness($this->image, 1);
}
// 添加文本
private function addText() {
$length = strlen($this->code);
for ($i = 0; $i < $length; $i++) {
$fontSize = rand(28, 36);
$angle = rand(-15, 15);
$x = 20 + $i * 30;
$y = rand(35, 45);
$color = imagecolorallocate($this->image, rand(0, 100), rand(0, 100), rand(0, 100));
// 使用内置字体
imagettftext($this->image, $fontSize, $angle, $x, $y, $color, __DIR__ . '/simkai.ttf', $this->code[$i]);
}
}
// 将图像转换为ASCII
public function convertToAscii($resolution = 2) {
$asciiArt = '';
for ($y = 0; $y < $this->height; $y += $resolution) {
for ($x = 0; $x < $this->width; $x += $resolution) {
$rgb = imagecolorat($this->image, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
// 计算亮度
$brightness = (0.3 * $r + 0.59 * $g + 0.11 * $b) / 255;
// 根据亮度选择ASCII字符
$charIndex = (int)($brightness * (count($this->asciiChars) - 1));
$asciiArt .= $this->asciiChars[$charIndex];
}
$asciiArt .= "\n";
}
return $asciiArt;
}
// 输出图像
public function outputImage() {
header('Content-Type: image/png');
imagepng($this->image);
imagedestroy($this->image);
exit;
}
// 输出ASCII
public function outputAscii() {
$ascii = $this->convertToAscii();
echo '<pre>' . htmlspecialchars($ascii) . '</pre>';
}
}
// 处理请求
if (isset($_GET['image'])) {
$captcha = new AsciiCaptcha();
$captcha->outputImage();
} elseif (isset($_GET['ascii'])) {
//$captcha = new AsciiCaptcha();
//$captcha->outputAscii();
} elseif (isset($_POST['verify'])) {
$userInput = $_POST['captcha_input'];
$storedCode = $_SESSION['captcha_code'] ?? '';
if (strtoupper($userInput) === strtoupper($storedCode)) {
$message = "验证成功!";
} else {
$message = "验证失败,请重试。";
}
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ASCII验证码生成器</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
color: #333;
}
.container {
background: white;
border-radius: 10px;
padding: 20px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
h1 {
text-align: center;
color: #2c3e50;
}
.captcha-container {
display: flex;
flex-direction: column;
align-items: center;
margin: 20px 0;
}
.captcha-image {
margin: 15px 0;
padding: 10px;
background: #eee;
border-radius: 5px;
}
.captcha-ascii {
font-family: monospace;
line-height: 1;
letter-spacing: 1px;
background: #eee;
padding: 15px;
border-radius: 5px;
margin: 15px 0;
white-space: pre;
overflow-x: auto;
}
.btn {
background: #3498db;
color: white;
border: none;
padding: 10px 15px;
border-radius: 5px;
cursor: pointer;
margin: 5px;
transition: background 0.3s;
}
.btn:hover {
background: #2980b9;
}
.form-group {
margin: 15px 0;
text-align: center;
}
input[type="text"] {
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
width: 200px;
}
.message {
padding: 10px;
border-radius: 5px;
margin: 15px 0;
text-align: center;
}
.success {
background: #d4edda;
color: #155724;
}
.error {
background: #f8d7da;
color: #721c24;
}
.options {
display: flex;
justify-content: center;
margin: 20px 0;
}
</style>
</head>
<body>
<div class="container">
<h1>ASCII验证码生成器</h1>
<div class="options">
<a href="<?php echo $_SERVER['PHP_SELF']; ?>" class="btn">刷新</a>
</div>
<div class="captcha-container">
<div class="captcha-ascii">
<?php
$captcha = new AsciiCaptcha();
$captcha->outputAscii();
?>
</div>
<form method="POST" action="">
<div class="form-group">
<input type="text" name="captcha_input" placeholder="请输入验证码" required>
<button type="submit" name="verify" class="btn">验证</button>
</div>
</form>
<?php if (isset($message)): ?>
<div class="message <?php echo strpos($message, '成功') !== false ? 'success' : 'error'; ?>">
<?php echo $message; ?>
</div>
<?php endif; ?>
</div>
<div style="margin-top: 30px; padding: 15px; background: #f8f9fa; border-radius: 5px;">
<h3>关于此实现</h3>
<p>这个PHP验证码系统:</p>
<ul>
<li>首先生成一个普通的图像验证码</li>
<li>然后将图像转换为ASCII艺术形式</li>
<li>使用字符表示图像的明暗程度</li>
</ul>
</div>
</div>
</body>
</html>