实现一个动态验证码生成器:Canvas与JavaScript的完美结合
验证码(CAPTCHA)是现代网站中常见的安全机制,用于区分人类用户和自动化程序。本文将详细介绍如何使用HTML5 Canvas和JavaScript创建一个美观且功能完整的验证码生成器。
一、核心功能概述
这个验证码生成器具有以下特点:
-
随机生成4位字母数字组合(区分大小写)
-
每个字符随机旋转一定角度增加识别难度
-
随机颜色字符增强视觉效果
-
添加干扰线和干扰点防止OCR识别
-
点击验证码可刷新生成新验证码
-
将生成的验证码值存储在DOM属性中便于验证
二、HTML结构
首先需要一个简单的HTML结构作为基础:
<canvas id="canvas" width="120" height="40"></canvas>
这个canvas元素将作为我们绘制验证码的画布。
三、JavaScript实现解析
1. 初始化与事件绑定
$(function () {code_draw();// 点击后刷新验证码$("#canvas").on('click', function () {code_draw();});
});
这段代码在文档加载完成后:
-
立即调用
code_draw()函数生成初始验证码 -
为canvas元素绑定点击事件,点击时重新生成验证码
2. 验证码绘制主函数
code_draw()函数是核心功能所在:
function code_draw() {// 获取canvas尺寸var canvas_width = $('#canvas').width();var canvas_height = $('#canvas').height();// 获取canvas上下文var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");// 设置canvas尺寸(重要!防止缩放导致的模糊)canvas.width = canvas_width;canvas.height = canvas_height;// 定义验证码字符集var sCode = "A,B,C,E,F,G,H,J,K,L,M,N,P,Q,R,S,T,W,X,Y,Z,1,2,3,4,5,6,7,8,9,0";var aCode = sCode.split(",");var aLength = aCode.length;// 存储生成的验证码值var value = [];// 绘制4个随机字符for (var i = 0; i <= 3; i++) {var j = Math.floor(Math.random() * aLength); // 随机索引var deg = Math.random() * 30 * Math.PI / 180; // 随机旋转角度(弧度制)var txt = aCode[j]; // 获取随机字符value[i] = txt.toLowerCase(); // 存储小写形式(便于后续验证不区分大小写)// 字符位置计算var x = 10 + i * 20;var y = 20 + Math.random() * 8;// 设置字体样式context.font = "bold 23px 微软雅黑";// 变换坐标系实现旋转context.translate(x, y);context.rotate(deg);// 绘制文字context.fillStyle = code_randomColor();context.fillText(txt, 0, 0);// 恢复坐标系context.rotate(-deg);context.translate(-x, -y);}// 将验证码值存储到data属性value = value.join("");$('#canvas').attr('data-code', value);// 绘制干扰线for (var i = 0; i <= 5; i++) {context.strokeStyle = code_randomColor();context.beginPath();context.moveTo(Math.random() * canvas_width, Math.random() * canvas_height);context.lineTo(Math.random() * canvas_width, Math.random() * canvas_height);context.stroke();}// 绘制干扰点for (var i = 0; i <= 30; i++) {context.strokeStyle = code_randomColor();context.beginPath();var x = Math.random() * canvas_width;var y = Math.random() * canvas_height;context.moveTo(x, y);context.lineTo(x + 1, y + 1);context.stroke();}
}
3. 随机颜色生成
function code_randomColor() {var r = Math.floor(Math.random() * 256);var g = Math.floor(Math.random() * 256);var b = Math.floor(Math.random() * 256);return "rgb(" + r + "," + g + "," + b + ")";
}
这个辅助函数生成随机的RGB颜色值,用于字符、干扰线和干扰点的着色。
四、关键技术点解析
-
Canvas坐标系变换:
-
使用
translate()和rotate()实现字符的随机旋转 -
注意在绘制完一个字符后需要恢复坐标系状态
-
-
防模糊处理:
-
通过设置
canvas.width和canvas.height而不仅仅是CSS尺寸,确保在高DPI设备上清晰显示
-
-
验证码存储:
-
将生成的验证码值存储在canvas的
data-code属性中,便于后续验证时获取
-
-
安全增强:
-
干扰线和干扰点的随机分布有效防止简单的图像识别
-
字符随机旋转增加机器识别难度
-
五、实际应用与验证
在实际使用时,可以将用户输入与canvas的data-code属性值进行比较:
function validateCode(input) {var canvasCode = $('#canvas').attr('data-code').toLowerCase();return input.toLowerCase() === canvasCode;
}
六、优化建议
-
增加字符间距随机性:当前字符间距固定为20px,可以增加随机性
-
更多字体变化:可以引入多种字体随机选择
-
背景色随机:为canvas添加随机背景色增强视觉效果
-
扭曲变形:对字符进行更复杂的变形处理
-
响应式设计:根据容器大小自动调整验证码尺寸
七、完整代码示例
<!DOCTYPE html>
<html>
<head><title>验证码示例</title><script src="https://code.jquery.com/jquery-3.6.0.min.js"></script><style>#canvas {border: 1px solid #ddd;cursor: pointer;}</style>
</head>
<body><canvas id="canvas" width="120" height="40"></canvas><script>$(function () {code_draw();// 点击后刷新验证码$("#canvas").on('click', function () {code_draw();});});function code_draw() {var canvas_width = $('#canvas').width();var canvas_height = $('#canvas').height();var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");canvas.width = canvas_width;canvas.height = canvas_height;var sCode = "A,B,C,E,F,G,H,J,K,L,M,N,P,Q,R,S,T,W,X,Y,Z,1,2,3,4,5,6,7,8,9,0";var aCode = sCode.split(",");var aLength = aCode.length;var value = [];for (var i = 0; i <= 3; i++) {var j = Math.floor(Math.random() * aLength);var deg = Math.random() * 30 * Math.PI / 180;var txt = aCode[j];value[i] = txt.toLowerCase();var x = 10 + i * 20;var y = 20 + Math.random() * 8;context.font = "bold 23px 微软雅黑";context.translate(x, y);context.rotate(deg);context.fillStyle = code_randomColor();context.fillText(txt, 0, 0);context.rotate(-deg);context.translate(-x, -y);}value = value.join("");$('#canvas').attr('data-code', value);for (var i = 0; i <= 5; i++) {context.strokeStyle = code_randomColor();context.beginPath();context.moveTo(Math.random() * canvas_width, Math.random() * canvas_height);context.lineTo(Math.random() * canvas_width, Math.random() * canvas_height);context.stroke();}for (var i = 0; i <= 30; i++) {context.strokeStyle = code_randomColor();context.beginPath();var x = Math.random() * canvas_width;var y = Math.random() * canvas_height;context.moveTo(x, y);context.lineTo(x + 1, y + 1);context.stroke();}}function code_randomColor() {var r = Math.floor(Math.random() * 256);var g = Math.floor(Math.random() * 256);var b = Math.floor(Math.random() * 256);return "rgb(" + r + "," + g + "," + b + ")";}</script>
</body>
</html>
八、总结
本文详细介绍了如何使用Canvas和JavaScript创建一个功能完善的验证码生成器。通过随机字符、颜色、旋转角度以及干扰元素的组合,我们实现了一个既美观又具有一定安全性的验证码系统。这种前端验证码虽然不能替代服务器端的安全验证,但作为第一道防线,能有效阻止简单的自动化脚本攻击。
开发者可以根据实际需求进一步扩展功能,如增加更多安全特性或改进用户体验。希望这篇文章能帮助你理解验证码的实现原理,并在你的项目中应用这些技术。
相关文章:
实现一个动态验证码生成器:Canvas与JavaScript的完美结合
验证码(CAPTCHA)是现代网站中常见的安全机制,用于区分人类用户和自动化程序。本文将详细介绍如何使用HTML5 Canvas和JavaScript创建一个美观且功能完整的验证码生成器。 一、核心功能概述 这个验证码生成器具有以下特点: 随机生…...
python中 “with” 关键字的取舍问题
自动管理资源(自动关闭文件) 当你使用 with 打开文件时,文件会在 with 代码块结束后自动关闭,无论是否发生异常。这意味着你不需要显式地调用 f.close() 来关闭文件 示例: with open("words.txt", "r…...
【区块链安全 | 第三十九篇】合约审计之delegatecall(一)
文章目录 外部调用函数calldelegatecallcall 与 delegatecall 的区别示例部署后初始状态调用B.testCall()函数调用B.testDelegatecall()函数区别总结漏洞代码代码审计攻击代码攻击原理解析攻击流程修复建议审计思路外部调用函数 在 Solidity 中,常见的两种底层外部函数调用方…...
Nginx部署spa单页面的小bug
没部署过,都是给后端干的,自己尝试部署了一个下午终于成功了 我遇到的最大的bug是进入后只有首页正常显示 其他页面全是404,于是问问问才知道,需要这个 location / { try_files $uri $uri/ /index.html; } 让…...
linux多线(进)程编程——(6)共享内存
前言 话说进程君的儿子经过父亲点播后就开始闭关,它想要开发出一种全新的传音神通。他想,如果两个人的大脑生长到了一起,那不是就可以直接知道对方在想什么了吗,这样不是可以避免通过语言传递照成的浪费吗? 下面就是它…...
【愚公系列】《Python网络爬虫从入门到精通》050-搭建 Scrapy 爬虫框架
🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! 👉 江湖人称"愚公搬代码",用七年如一日的精神深耕技术领域,以"…...
信息安全管理与评估2021年国赛正式卷答案截图以及十套国赛卷
2021年全国职业院校技能大赛高职组 “信息安全管理与评估”赛项 任务书1 赛项时间 共计X小时。 赛项信息 赛项内容 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段 平台搭建与安全设备配置防护 任务1 网络平台搭建 任务2 网络安全设备配置与防护 第二…...
讲解贪心算法
贪心算法是一种常用的算法思想,其在解决问题时每一步都做出在当前状态下看起来最优的选择,从而希望最终能够获得全局最优解。C作为一种流行的编程语言,可以很好地应用于贪心算法的实现。下面我们来讲一篇关于C贪心算法的文章。 目录 贪心算法…...
高并发秒杀系统设计:关键技术解析与典型陷阱规避
电商、在线票务等众多互联网业务场景中,高并发秒杀活动屡见不鲜。这类活动往往在短时间内会涌入海量的用户请求,对系统架构的性能、稳定性和可用性提出了极高的挑战。曾经,高并发秒杀架构设计让许多开发者望而生畏,然而࿰…...
微信小程序实战案例 - 餐馆点餐系统 阶段 2 – 购物车
阶段 2 – 购物车(超详细版) 目标 把“加入购物车”做成 全局状态,任何页面都能读写在本地 持久化(关闭小程序后购物车仍在)新建 购物车页:数量增减、总价实时计算、去结算入口打 Git Tag v2.0‑cart 1. …...
Qt 元对象系统探秘:从 Q_OBJECT 到反射编程的魔法之旅
背景说明:Qt 背后的「魔法引擎」 如果你曾用 Qt 写过信号槽,或是在设计器里拖过控件改属性,一定对这个框架的“动态性”印象深刻: 无需手动调用,信号能自动连接到槽函数;无需编译重启,界面上修…...
sql 向Java的映射
优化建议,可以在SQL中控制它的类型 在 MyBatis 中,如果返回值类型设置为 java.util.Map,默认情况下可以返回 多行多列的数据...
Visual Studio未能加载相应的Package包弹窗报错
环境介绍: visulal studio 2019 问题描述: 起因:安装vs扩展插件后,重新打开Visual Studio,报了一些列如下的弹窗错误,即使选择不继续显示该错误,再次打开后任然报错; 解决思路&am…...
【HD-RK3576-PI】Docker搭建与使用
硬件:HD-RK3576-PI 软件:Linux6.1Ubuntu22.04 1.Docker 简介 Docker 是一个开源的应用容器引擎,基于 Go 语言开发,遵循 Apache 2.0 协议。它可以让开发者将应用程序及其依赖项打包到一个轻量级、可移植的容器中,并在任…...
C语言实现用户管理系统
以下是一个简单的C语言用户管理系统示例,它实现了用户信息的添加、删除、修改和查询功能。代码中包含了详细的注释和解释,帮助你理解每个部分的作用。 #include <stdio.h> #include <stdlib.h> #include <string.h>#define MAX_USERS…...
【websocket】使用案例( JSR 356 标准)
目录 一、JSR 356方式:简单示例 1、引入依赖 2、注册端点扫描器 3、编写通过注解处理生命周期和消息 4、细节解读 5、总结 二、聊天室案例 方案流程 1、引入依赖 2、注册端点扫描器 3、编写一个配置类,读取httpsession 4、编写通过注解处理生…...
tcpdump`是一个非常强大的命令行工具,用于在网络上捕获并分析数据包
通过 tcpdump,你可以抓取网络流量,诊断网络问题,或分析通信协议的细节。下面是如何在 Linux 上使用 tcpdump 进行抓包的详细步骤。 1. 安装 tcpdump 在大多数 Linux 发行版中,tcpdump 是默认安装的。如果没有安装,可…...
IS-IS中特殊字段——OL过载
文章目录 OL 过载位 🏡作者主页:点击! 🤖Datacom专栏:点击! ⏰️创作时间:2025年04月13日20点12分 OL 过载位 路由过载 使用 IS-IS 的过载标记来标识过载状态 对设备设置过载标记后ÿ…...
【时频谱分析】快速谱峭度
算法配置页面,也可以一键导出结果数据 报表自定义绘制 获取和下载【PHM学习软件PHM源码】的方式 获取方式:Docshttps://jcn362s9p4t8.feishu.cn/wiki/A0NXwPxY3ie1cGkOy08cru6vnvc...
Spring Boot 支持的内嵌服务器(Tomcat、Jetty、Undertow、Netty(用于 WebFlux 响应式应用))详解
Spring Boot 支持的内嵌服务器详解 1. 支持的内嵌服务器 Spring Boot 默认支持以下内嵌服务器: Tomcat(默认)JettyUndertowNetty(用于 WebFlux 响应式应用) 2. 各服务器使用示例 (1) Tomcat(默认…...
微软Exchange管理中心全球范围宕机
微软已确认Exchange管理中心(Exchange Admin Center,EAC)发生全球性服务中断,导致管理员无法访问关键管理工具。该故障被标记为关键服务事件(编号EX1051697),对依赖Exchange Online的企业造成广…...
基于AI的Web应用防火墙(AppWall)实战:漏洞拦截与威胁情报集成
摘要:针对Web应用面临的OWASP、CVE等漏洞攻击,本文结合群联AI云防护系统的AppWall模块,详解AI规则双引擎的防御原理,并提供漏洞拦截配置与威胁情报集成代码示例。 一、Web应用安全挑战与AppWall优势 传统WAF依赖规则库更新滞后&a…...
基于Qt的串口通信工具
程序介绍 该程序是一个基于Qt的串口通信工具,专用于ESP8266 WiFi模块的AT指令配置与调试。主要功能包括: 1. 核心功能 串口通信:支持串口开关、参数配置(波特率、数据位、停止位、校验位)及数据收发。 AT指令操作&a…...
CSS 字体学习笔记
在网页设计中,字体的使用对于提升用户体验和页面美观性至关重要。CSS 提供了一系列字体属性,用于控制文本的显示效果。以下是对 CSS 字体属性的详细学习笔记。 一、字体系列(font-family) 1. 字体系列的分类 在 CSS 中…...
《MySQL是怎样运行的》总结笔记
内容太多,主要总结一些自己认为重要的,另外太基础常见可能不会总结上。 字符集和比较规则 MySQL会通过把字符串编码后再进行比较大小并排序,有一些很早的字符集可能会不支持中文,比如ASCII、ISO 8859-1,现在最常用的…...
力扣每日打卡 1922. 统计好数字的数目 (中等)
力扣 1922. 统计好数字的数目 中等 前言一、题目内容二、解题方法1. 暴力解法(会超时,此法不通)2. 快速幂运算3. 组合计数的思维逻辑分析组合计数的推导例子分析思维小结论 4.官方题解4.1 方法一:快速幂 三、快速幂运算快速幂运算…...
上层 Makefile 控制下层 Makefile 的方法
在复杂的项目中,通常会将项目划分为多个模块或子项目,每个模块都有自己的 Makefile。上层 Makefile 的作用是协调和控制这些下层 Makefile 的构建过程。下面是几种常见的示例,实现上层 Makefile 对下层 Makefile 的控制。 直接调用࿱…...
html简易实现推箱子小游戏原理(易上手)
实现效果 使用方向键移动,将橙色箱子推到绿色目标区域(黑色块为墙,白色块为可通过区域,蓝球为小人) 实现过程 <!DOCTYPE html> <html> <head><title>推箱子小游戏</title><style&g…...
搭建一个Spring Boot聚合项目
1. 创建父项目 打开IntelliJ IDEA,选择 New Project。 在创建向导中选择 Maven,确保选中 Create from archetype,选择 org.apache.maven.archetypes:maven-archetype-quickstart。 填写项目信息: GroupId:com.exampl…...
字符串与栈和队列-算法小结
字符串 双指针 反转字符串(双指针) 力扣题目链接 void reverseString(vector<char>& s) {for (int i 0, j s.size() - 1; i < s.size()/2; i, j--) {swap(s[i],s[j]);} }反转字符串II 力扣题目链接 遍历字符串的过程中,只要让 i (2 * k)&#…...
