Java验证码
文章目录
- 一、验证码概述
- 二、Java原生验证码
- 1、随机数字验证码
- 2、随机数字和字母验证码
- 3、运算验证码
- 三、引入三方验证码
一、验证码概述
验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序
验证码的作用:
- 防止刷票、论坛灌水、刷页
- 防止黑客恶意破解密码,盗取用户数据
验证码通常使用一些线条和一些不规则的字符组成,主要作用是为了防止一些黑客把密码数据化盗取。有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登录尝试,实际上使用验证码是现在很多网站通行的方式(比如招商银行的网上个人银行,百度社区),我们利用比较简易的方式实现了这个功能。虽然登录麻烦一点,但是对网友的密码安全来说这个功能还是很有必要,也很重要
- 防止恶意注册、登录
验证码一般是防止批量注册的,人眼看起来都费劲,何况是机器。几乎所有正规的论坛都要求注册时输入验证码,这是为了防止乱发垃圾广告的人用注册机来恶意注册
二、Java原生验证码
创建好需要保存的Bean类,保存好结果和过期时间等,最后直接把这个类放在session中
public class CheckCode {// 验证码字符private String code;// 过期时间private LocalDateTime expireTime;/*** @param code 验证码字符* @param expireTime 过期时间,单位秒*/public CheckCode(String code, int expireTime) {this.code = code;this.expireTime = LocalDateTime.now().plusSeconds(expireTime);}public CheckCode(String code) {// 默认验证码 60 秒后过期this(code, 60);}// 是否过期public boolean isExpired() {return this.expireTime.isBefore(LocalDateTime.now());}public String getCode() {return this.code;}
}
1、随机数字验证码
// 验证码图片边框宽度
int WIDTH = 120;
// 验证码图片边框高度
int HEIGHT = 45;
// 验证码有效时间 60s
int expireIn = 60;// 普通验证码
int length = 4; // 验证码位数/*** 普通验证码
*/
public void createNumberImageCode(HttpServletRequest request,HttpServletResponse response) {// 设置响应报头信息response.setHeader("Pragma", "No-cache");response.setHeader("Cache-Control", "no-cache");response.setDateHeader("Expires", 0);// 设置响应的MIME类型response.setContentType("image/jpeg");BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);Graphics g = image.getGraphics();Random random = new Random();g.setColor(getRandColor(185, 250));g.fillRect(0, 0, WIDTH, HEIGHT);g.setFont(new Font("Times New Roman", Font.ITALIC, 35));g.setColor(getRandColor(160, 200));for (int i = 0; i < 155; i++) {int x = random.nextInt(WIDTH);int y = random.nextInt(HEIGHT);int xl = random.nextInt(12);int yl = random.nextInt(12);g.drawLine(x, y, x + xl, y + yl);}StringBuilder sRand = new StringBuilder();for (int i = 0; i < length; i++) {String rand = String.valueOf(random.nextInt(10));sRand.append(rand);g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));g.drawString(rand, 25 * i + 12, 32);}g.dispose();// 放入session缓存,默认60s过期CheckCode checkCode = new CheckCode(sRand.toString(),expireIn);HttpSession se = request.getSession();se.setAttribute(Constants.KAPTCHA_SESSION_KEY, checkCode);try {OutputStream os = response.getOutputStream();// 输出图像到页面ImageIO.write(image, "JPEG", os);} catch (IOException e) {e.printStackTrace();}}private Color getRandColor(int fc, int bc) {Random random = new Random();if (fc > 255) {fc = 255;}if (bc > 255) {bc = 255;}int r = fc + random.nextInt(bc - fc);int g = fc + random.nextInt(bc - fc);int b = fc + random.nextInt(bc - fc);return new Color(r, g, b);
}
2、随机数字和字母验证码
// 验证码图片边框宽度
int WIDTH = 120;
// 验证码图片边框高度
int HEIGHT = 45;
// 验证码有效时间 60s
int expireIn = 60;// 普通验证码
int length = 4; // 验证码位数public void createNumberAndLetterImageCode(HttpServletRequest request,HttpServletResponse response) throws IOException {// 设置响应报头信息response.setHeader("Pragma", "No-cache");response.setHeader("Cache-Control", "no-cache");response.setDateHeader("Expires", 0);// 设置响应的MIME类型response.setContentType("image/jpeg");//画板BufferedImage image = new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB);//画笔Graphics g = image.getGraphics();//字体Font font = new Font("微软雅黑", Font.BOLD,35);//设置字体g.setFont(font);//引入背景图片g.fillRect(0, 0, WIDTH, HEIGHT);//随机数Random random = new Random();//要随机的字符串String template = "123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";StringBuilder s = new StringBuilder();char tempNum;for (int i = 0; i < length; i++){//获取随机出的字符int tempIndex = random.nextInt(template.length()-1);tempNum = template.charAt(tempIndex);//拼成字符串s.append(tempNum);//设置颜色Color color = new Color(20+random.nextInt(110),20+random.nextInt(110),random.nextInt(110));g.setColor(color);//字母写入图片g.drawString(String.valueOf(tempNum),25 * i + 12, 32);}// 放入session缓存,默认60s过期CheckCode checkCode = new CheckCode(sRand.toString(),expireIn);HttpSession se = request.getSession();se.setAttribute(Constants.KAPTCHA_SESSION_KEY, checkCode);//获取流发送给前台ServletOutputStream ots = response.getOutputStream();ImageIO.write(image,"JPEG",ots);}
3、运算验证码
// 公共部分
// 验证码图片边框宽度
int WIDTH = 120;
// 验证码图片边框高度
int HEIGHT = 45;
// 验证码有效时间 60s
int expireIn = 60;// 运算验证码
// 验证码字体高度
int FONT_HEIGHT = HEIGHT - 12;
// 验证码干扰线条数
int INTERFERENCE_LINE = 4;/*** 生成运算验证码*/
public void createSpecialImageCode(HttpServletRequest request,HttpServletResponse response){// 设置响应报头信息response.setHeader("Pragma", "No-cache");response.setHeader("Cache-Control", "no-cache");response.setDateHeader("Expires", 0);// 设置响应的MIME类型response.setContentType("image/jpeg");BufferedImage image = new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB);Font mFont = new Font("Arial", Font.PLAIN, 18);Graphics g = image.getGraphics();Random rd = new Random();// 设置背景颜色g.setColor(new Color(rd.nextInt(55) + 200, rd.nextInt(55) + 200, rd.nextInt(55) + 200));g.fillRect(0, 0, WIDTH, HEIGHT);// 设置字体g.setFont(mFont);// 画边框g.setColor(Color.black);g.drawRect(0, 0, WIDTH - 1, HEIGHT - 1);// 验证码字符串String text = getText();// 运算表达式String operationExpression = text.substring(0, text.lastIndexOf("@") - 1);// 计算结果String result = text.substring(text.lastIndexOf("@") + 1);// 放入session缓存,默认60s过期CheckCode checkCode = new CheckCode(result,expireIn);HttpSession se = request.getSession();se.setAttribute(Constants.KAPTCHA_SESSION_KEY, checkCode);g.setColor(new Color(rd.nextInt(200), rd.nextInt(200), rd.nextInt(200)));// 根据画笔颜色绘制字符g.drawString(operationExpression, 5, FONT_HEIGHT);int r = 0;int gg = 0;int b = 0;// 绘制干扰线int x1, y1, x2, y2;for (int i = 0; i < INTERFERENCE_LINE; i++) {// 随机生成rgb颜色值,并设置画笔颜色r = rd.nextInt(255);gg = rd.nextInt(255);b = rd.nextInt(255);g.setColor(new Color(r, gg, b));x1 = rd.nextInt(WIDTH);y1 = rd.nextInt(HEIGHT);x2 = rd.nextInt(WIDTH);y2 = rd.nextInt(HEIGHT);// 绘制线条g.drawLine(x1, y1, x2, y2);}// 释放图形资源g.dispose();try {OutputStream os = response.getOutputStream();// 输出图像到页面ImageIO.write(image, "JPEG", os);} catch (IOException e) {e.printStackTrace();}
}/*** 获取运算验证码*/
private String getText() {Random random = new Random(System.currentTimeMillis());StringBuilder result = new StringBuilder(); // 运算验证码结果int x = random.nextInt(51);int y = random.nextInt(51);int operationalRules = random.nextInt(4);switch (operationalRules) {case 0:result = add(x, y);break;case 1:result = subtract(x, y);break;case 2:result = multiply(x, y);break;case 3:result = divide(x, y);break;default:result = add(x, y);break;}return result.toString();
}
/*** 加法运算*/
private StringBuilder add(int x, int y) {StringBuilder result = new StringBuilder(); // 运算验证码结果result.append(x);result.append(" + ");result.append(y);result.append(" = ?@");result.append(x + y);return result;
}
/*** 减法运算*/
private StringBuilder subtract(int x, int y) {StringBuilder result = new StringBuilder(); // 运算验证码结果int max = Math.max(x, y);int min = Math.min(x, y);result.append(max);result.append(" - ");result.append(min);result.append(" = ?@");result.append(max - min);return result;
}
/*** 乘法运算*/
private StringBuilder multiply(int x, int y) {StringBuilder result = new StringBuilder(); // 运算验证码结果int value = x * y;result.append(x);result.append(value > 100 ? " + " : " * ");result.append(y);result.append(" = ?@");result.append(value > 100 ? x + y : x * y);return result;
}
/*** 除法运算*/
private StringBuilder divide(int x, int y) {StringBuilder result = new StringBuilder(); // 运算验证码结果int max = Math.max(x, y);int min = Math.min(x, y);if (min == 0) {multiply(max, min);} else if (max % min == 0) {result.append(max);result.append(" / ");result.append(min);result.append(" = ?@");result.append(max / min);} else {result.append(max);result.append(" % ");result.append(min);result.append(" = ?@");result.append(max % min);}return result;
}
三、引入三方验证码
三方验证码有很多,这里我就只举例一个
引入依赖
<!--验证码-->
<dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6.2</version>
</dependency>
编写代码
@GetMapping("/")
public void CodeCheck(HttpServletRequest request, HttpServletResponse response) throws IOException {// 设置请求头输入为图片类型response.setContentType("image/jpg");// 设置不用缓存,防止验证码不刷新response.setHeader("Pargam","No-cache");response.setHeader("Cache-Control","no-cache");// 设置过期时间,永不失效response.setDateHeader("Expires",0);// 算术类型(长,宽,几个数的运算)ArithmeticCaptcha captcha = new ArithmeticCaptcha(130, 48);captcha.setLen(3); // 几位数运算,默认是两位System.out.println(captcha.getArithmeticString()); // 获取运算公式 5x0+5=?System.out.println(captcha.text()); // 获取验证码结果// 图片英语字母数字类型//SpecCaptcha captcha = new SpecCaptcha(130, 48);// 英语字母数字gif类型的//GifCaptcha captcha = new GifCaptcha(130, 48,4);// 中文类型的//ChineseCaptcha captcha = new ChineseCaptcha(130, 48,3);// 中文gif类型//ChineseGifCaptcha captcha = new ChineseGifCaptcha(130, 48,4);// 输出验证码try {captcha.out(response.getOutputStream());} catch (IOException e) {e.printStackTrace();}
}
相关文章:

Java验证码
文章目录一、验证码概述二、Java原生验证码1、随机数字验证码2、随机数字和字母验证码3、运算验证码三、引入三方验证码一、验证码概述 验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全…...

5天带你读完《Effective Java》(四)
《Effective Java》是Java开发领域无可争议的经典之作,连Java之父James Gosling都说: “如果说我需要一本Java编程的书,那就是它了”。它为Java程序员提供了90个富有价值的编程准则,适合对Java开发有一定经验想要继续深入的程序员…...

探索密码学的未来:SM1、SM2、SM3、SM4、同态加密、密态计算、隐私计算和安全多方计算
密码算法在现代通信与信息安全中发挥着至关重要的作用,SM1、SM2、SM3、SM4、同态加密、密态计算、隐私计算和安全多方计算等密码算法被广泛应用于各种信息安全领域。本篇博客将会为大家介绍这些密码算法,以及它们在信息安全中的作用和应用。 一、SM1、SM…...

【教程】去水印开源工具Lama Cleaner在Windows的安装和使用
一、Lama Cleaner是什么? Lama Cleaner是一款开源且免费的人工学习图片去水印程序(个人主要学习用途),没有图片分辨率限制(个人使用暂未发现),并且保存的图片质量很高(个人觉得跟原…...

驾考笔记_2023
科目一1> 扣分制度1.1> 超速1.2> 超载1.3> 车牌1.4> 速记口诀2> 满分学习2.1> 消分学习2.2> 满分重考;3> 罚款 / 判刑3.1> 考证3.2> 审验教育3.3> 酒驾3.4> 200¥3.5> 500¥3.6> 2000¥…...

【架构师】跟我一起学架构——调用链
博客昵称:架构师Cool 最喜欢的座右铭:一以贯之的努力,不得懈怠的人生。 作者简介:一名Coder,软件设计师/鸿蒙高级工程师认证,在备战高级架构师/系统分析师,欢迎关注小弟! 博主小留言…...

[神经网络]Swin Transformer网络
一、概述 Swin Transformer是一个用了移动窗口的层级式Vision Transformer。 在图像领域,Transformer需要解决如下两个问题: ①尺度问题:同一语义的物体在图像中有不一样的尺度。(大小不同) ②Resolution过大:若以像素点作为单位&…...

【分布式】什么是分布式,分布式和集群的区别又是什么?答案在正文。
文章目录1. 什么是分布式 ?2. 分布式与集群的区别 ?3.用一个请求串起来4.一个简化的架构图5.分布式环境的特点6.分布式环境下面临的问题7.总结1. 什么是分布式 ? 分布式系统一定是由多个节点组成的系统。 其中,节点指的是计算机服务器,而且这些节点一…...

MyBatis框架的入门案例
MyBatis框架的入门案例 资源地址:https://download.csdn.net/download/weixin_41957626/87531373 1.MyBatis的配置 环境:基于maven的结构 1.1目录结构 1.2依赖包 <dependencies><!--mybatis--><dependency><groupId>org.mybatis…...

红黑树-随记
文章目录1.为什么hashmap用红黑树不用二叉树和平衡二叉树1.1 二叉树(Binary Search Tree)1.2 红黑树(Red Black Tree)1.3 平衡二叉树(Balence Binary Tree)也称AVT2.为什么mysql用b数,不用B数或…...

Python异常处理更新,正常和不正常的都在这里
嗨害大家好鸭!我是小熊猫~ 异常处理篇嗨害大家好鸭!我是小熊猫~Python标准异常💨什么是异常?不正常异常处理💨使用except而不带任何异常类型使用except而带多种异常类型try-finally 语句异常的参数触发异常用户自定义异…...

[数据结构]:10-二叉排序树(无头结点)(C语言实现)
目录 前言 已完成内容 二叉排序树实现 01-开发环境 02-文件布局 03-代码 01-主函数 02-头文件 03-BinarySearchTreeCommon.cpp 04-BinarySearchTreeFunction.cpp 结语 前言 此专栏包含408考研数据结构全部内容,除其中使用到C引用外,全为C语言…...

openstack浅析
** OpenStack是一个由多个组件组成的开源云计算平台,每个组件都有不同的功能和用途。 ** 组件构成 以下是OpenStack中一些常见的组件及其功能: Nova:用于管理虚拟机的组件,提供了虚拟机的创建、销毁、管理等功能。 Neutron&am…...

华为OD机试Golang解题 - 特异性双端队列 | 含思路
华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典文章目录 华为Od必看系列使用说明本期题目…...

代码随想录中:回溯算法的基础
回溯算法是一种暴力的搜索方式;回溯法一般与递归同时存在。 回溯法,一般可以解决如下几种问题: 组合问题:N个数里面按一定规则找出k个数的集合切割问题:一个字符串按一定规则有几种切割方式子集问题:一个…...

Android kotlin 系列讲解(进阶篇)Jetpack系列之LiveData
<<返回总目录 文章目录 一、LiveData是什么二、LiveData测试一、LiveData是什么 LiveData是Jetpack提供的一种响应式编程组件,它可以包括任何类型的数据,并在数据发生变化的时候通知给观察者。LiveData特别适合与ViewModel结合在一起使用,虽然它也可以单独在别的地方…...

如何判断有向无环图:构造有向无环图
拓扑序列:可以用来判断一个有向图是否有环! 拓扑排序可以判断有向图是否存在环。我们可以对任意有向图执行上述过程,在完成后检查A序列的长度。 若A序列的长度小于图中点的数量,则说明某些节点未被遍历,进而说明图中存…...

【2022.1.3】手脱压缩壳练习(含练习exe)
【2022.1.3】手脱压缩壳练习(含练习exe) 文章目录【2022.1.3】手脱压缩壳练习(含练习exe)0、简介1、单步跟踪法(#)方法介绍(0)练习exe下载(1)、查看源程序&am…...

【异或哈希】CF855 div3 F
感觉这道题跟之前有一题特别像,都是异或哈希感觉这种题应该很典,记录一下(66条消息) Codeforces Round #841 (Div. 2) and Divide by Zero【异或差分动态map维护】 2022 C. Even Subarrays_lamentropetion的博客-CSDN博客Problem - F - Codeforces题意&a…...

深度学习|改进两阶段鲁棒优化算法i-ccg
目录 1 主要内容 2 改进算法 2.1 CC&G算法的优势 2.2 i-CCG算法简介 3 结果对比 1 主要内容 自从2013年的求解两阶段鲁棒优化模型的列和约束生成算法(CC&G)被提出之后,基本没有实质性的创新,都是围绕该算法在各个领…...

C++11轻松打印本地时间
C11之前,想要获取时间并对其打印是有些困难的,因为C并没有标准时间库。想要对时间进行统计就需要调用C库,并且我们要考虑这样的调用是否能很好的封装到我们的类中。 C11之后,STL提供了 chrono 库,其让对时间的操作更加…...

Eureka - 总览
文章目录前言架构注册中心 Eureka Server服务提供者 Eureka Client服务消费者 Eureka Client总结资源前言 微服务(Microservices,一种软件架构风格)核心的组件包括注册中心,随着微服务的发展,出现了很多注册中心的解决…...

【算法设计-枚举、分治】素数、约数、质因数分解
文章目录1. 素数判定2. 素数筛选法3. 质因数分解4. 求一个数的约数5. 求两个数的最大公约数(GCD)6. 求两个数的最小公倍数(LCM)1. 素数判定 判定从 2 到sqrt(n)依次能否把 n 整除,若存在可以整除的数则说明 n 不是素数…...

【第十四届蓝桥杯】第三期模拟赛B组C++题解(待修正+持续更新-ing)
文章目录写在前面一、找最小数题目描述解题报告1、大体思路2、代码详解二、求列名题目描述解题报告1、大体思路2、代码详解三、求日期数题目描述解题报告1、大体思路2、代码详解四、取数题目描述解题报告1、大体思路2、代码详解五、最大连通分块题目描述解题报告1、大体思路2、…...

线程池和ThreadLocal详解
线程池和ThreadLocal详解线程池池化模式:线程池里的线程数量设定为多少比较合适?添加线程规则:实现原理:线程池实现任务复用的原理线程池状态:Executors 创线程池工具类手动创建(更推荐):自动创…...

[深入理解SSD系列综述 1.7] SSD固态存储市场发展分析与预测_固态存储技术发展方向(2022to2023)
前言 自2020年疫情爆发以来,远程办公、网上教育、流媒体等等应用引爆对消费电子及云服务的需求增长,全球数字化转型加速,带来了两年的闪存风光时刻。然而,进入2022年,在俄乌冲突、疫情重燃、通胀上升等一系列事件冲击下,全球经济下行风险加剧,对智能手机、PC等科技产品的…...

【2021.12.25】ctf逆向中常见加密算法和编码识别
【2021.12.25】ctf逆向中常见加密算法和编码识别(含exe及wp) 文章目录【2021.12.25】ctf逆向中常见加密算法和编码识别(含exe及wp)0、前言1、基础加密手法2、base64(1)原理:(2&#…...

【数据结构初阶】堆排序
目录 前言 概念 堆排序的实现 1.建堆 (1)堆向上调整算法 (2)堆的向下调整算法 2. 利用堆删除思想来进行排序 3.堆排序的时间复杂度 4.源码 总结 前言 前边我们学习了堆的实现,对堆的每个接口都进行了详细的讲…...

Day5: platformDriver-1
Platform Driver (1) Linux kernel中大部分设备可以归结为平台设备,因此大部分的驱动是平台驱动(patform driver) 什么是平台设备 平台设备是linux的设备模型中一类设备的抽象。 内核中的描述: Platform devices are devices t…...

开发手册——一、编程规约_7.控制语句
这篇文章主要梳理了在java的实际开发过程中的编程规范问题。本篇文章主要借鉴于《阿里巴巴java开发手册终极版》 下面我们一起来看一下吧。 1. 【强制】在一个 switch 块内,每个 case 要么通过 break / return 等来终止,要么注释说明程序将继续执行到哪…...