验证码介绍及生成与验证
验证码介绍及生成与验证
验证码
验证码(全自动区分计算机和人类的图灵测试,CAPTCHA ,Completely Automated Public Turing test to tell Computers and Humans Apart)是一种用于区分用户是人类还是自动化程序的安全机制,通过生成人类易识别、机器难破解的测试题目实现身份验证。
作用
- 防止恶意攻击:抵御机器人批量注册、暴力破解密码、刷票等行为。
- 保护数据安全:拦截网络爬虫非法抓取敏感信息。
- 提升系统稳定性:减少服务器因自动化请求导致的过载风险。
常见类型
类型 | 示例 | 特点 |
传统文本验证码 | 扭曲字母/数字组合 | 简单易实现,但易被OCR技术破解 |
图像识别验证码 | 点击包含“红绿灯”的图片 | 依赖图像语义理解,机器识别难度较高 |
短信/邮件验证码 | 发送6位数字到用户手机/邮箱 | 依赖真实身份绑定,安全性强 |
行为验证码 | 滑动拼图、点选汉字 | 通过交互行为特征判断人类操作 |
智能无感验证 | Google reCAPTCHA v3 | 后台分析用户行为,无需主动操作 |
下面以传统文本验证码为例给出演示代码,特别提示,为简化实现,下面的演示验证码生成与验证示例都是在客户端实现的,仅适用于教学场景,并且验证码未设置失效时间与防重放机制,实际生产必须将验证码生成、存储、验证逻辑全部移至服务端,并综合运用加密、干扰技术、限流防御和监控告警,才能有效抵御自动化攻击与数据篡改风险。
客户端验证码生成与验证示例代码(HTML + JavaScript实现)先看运行效果:
源码如下:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>验证码生成与验证</title>
<style>
body {
font-family: "微软雅黑", sans-serif;
padding: 10px;
background: #333333;
color: #eeeeee;
display: block;
}
h1 {
text-align: center;
margin: 100px;
}
.container {
text-align: center;
margin: 0 auto;
width: 1000px;
height: 300px;
font-size: 1.1em; /* */
}
#captchaInput {
font-size: 2em;
width: 220px;
}
#captchaImg {
display: block;
margin: 10px auto; /* 上下边距 */
width: 180px; /* 图片显示尺寸 */
height: 50px;
}
button {
font-size: 2em;
background-color: #2196F3;
margin: 10px; /* 增加按钮间距 */
}
</style>
</head>
<body>
<div class="container"> <!-- 同步修正类名 -->
<h1>客户端验证码生成与验证</h1>
<img id="captchaImg" alt="Captcha Image">
<input type="text" id="captchaInput" placeholder="请输入验证码">
<button id="validateBtn">验证</button>
<button id="regenerateBtn">重新生成</button>
<script>
let currentCaptchaInfo;
function generateCaptcha(length = 6) {
const hexChars = '0123456789ABCDEF';
let captchaCode = '';
// 生成验证码文本
for (let i = 0; i < length; i++) {
captchaCode += hexChars[Math.floor(Math.random() * hexChars.length)];
}
// 配置画布参数
const canvas = document.createElement('canvas');
canvas.width = 180; // 画布避免溢出
canvas.height = 50;
const ctx = canvas.getContext('2d');
// 绘制背景
ctx.fillStyle = '#f0f0f0';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 字符绘制参数
const baseX = 20; // 起始X坐标
const charSpacing = 25; // 字符间距
ctx.font = '36px Courier New'; // 使用等宽字体
for (let i = 0; i < captchaCode.length; i++) {
ctx.fillStyle = '#ff0055';
// 生成有限旋转角度(-45°~45°)
const angle = (Math.random() - 0.5) * 90;
ctx.save();
// 定位到字符中心点
ctx.translate(baseX + (i * charSpacing), 30);
ctx.rotate(angle * Math.PI / 180);
ctx.fillText(captchaCode[i], -6, 8); // 微调字符位置
ctx.restore();
}
return {
code: captchaCode,
imageUrl: canvas.toDataURL()
};
}
// 初始化验证码
window.onload = () => {
regenerateCaptcha();
};
function regenerateCaptcha() {
currentCaptchaInfo = generateCaptcha();
document.getElementById('captchaImg').src = currentCaptchaInfo.imageUrl;
document.getElementById('captchaInput').value = '';
}
// 按钮事件监听
document.getElementById('regenerateBtn').addEventListener('click', regenerateCaptcha);
document.getElementById('validateBtn').addEventListener('click', () => {
const userInput = document.getElementById('captchaInput').value.toUpperCase();
userInput === currentCaptchaInfo.code ?
alert('验证成功!') : alert('验证失败!');
regenerateCaptcha();
});
</script>
</div>
</body>
</html>