JAVA生成验证码

news/2025/1/4 10:10:56/文章来源:https://www.cnblogs.com/guliang/p/18645531

1、生成方式(验证码字符串、图片验证码、base64验证码图片)

/*** @description:  使用方式1: 直接获取验证码字符串,前端进行自定义渲染* @date: 2024/12/16 11:37* @param  * @return java.lang.String*/ @GetMapping('/getCode')public String getCode() throws Exception{String code = VerifyUtil.newBuilder().build().createCode();// 这里可以将验证码存入redis,以便后续进行校验..return code;}/*** @description:  使用方式2: 直接输出图片验证码* @date: 2024/12/16 11:38* @param response * @return void*/ @GetMapping('/getImageCode')public void getImageCode(HttpServletResponse response) throws Exception{Object[] objs = VerifyUtil.newBuilder().setWidth(120)   //设置图片的宽度.setHeight(35)   //设置图片的高度.setSize(6)      //设置字符的个数.setLines(10)    //设置干扰线的条数.setFontSize(25) //设置字体的大小.setTilt(true)   //设置是否需要倾斜.setBackgroundColor(Color.WHITE) //设置验证码的背景颜色.build()         //构建VerifyUtil项目.createCodeAndImage();  //生成图片
String code = (String) objs[0];// 获取验证码// 这里可以将验证码存入redis,以便后续进行校验..//直接输出验证码图片BufferedImage image = (BufferedImage) objs[1];response.setContentType('image/png');OutputStream os = response.getOutputStream();ImageIO.write(image, 'png', os);}/*** @description: 使用方式3: 输出base64验证码图片* @date: 2024/12/16 11:39* @param  * @return java.lang.String*/ @GetMapping('/getBase64ImageCode')public String getBase64ImageCode() throws Exception{Object[] objs = VerifyUtil.newBuilder().setWidth(120)   //设置图片的宽度.setHeight(35)   //设置图片的高度.setSize(6)      //设置字符的个数.setLines(10)    //设置干扰线的条数.setFontSize(25) //设置字体的大小.setTilt(true)   //设置是否需要倾斜.setBackgroundColor(Color.WHITE) //设置验证码的背景颜色.build()         //构建VerifyUtil项目.createCodeAndBase64Image();  //生成图片
String code = (String) objs[0];// 获取验证码String base64Image = (String) objs[1];// 这里可以将验证码存入redis,以便后续进行校验..return base64Image;}

2、验证码工具类

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.Random;public class VerifyUtil {// 默认验证码字符集private static final char[] chars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};// 默认字符数量private final Integer SIZE;// 默认干扰线数量private final int LINES;// 默认宽度private final int WIDTH;// 默认高度private final int HEIGHT;// 默认字体大小private final int FONT_SIZE;// 默认字体倾斜private final boolean TILT;private final Color BACKGROUND_COLOR;private final String BASE64_IMAGE_PERFIX = 'data:image/jpeg;base64,';/*** 初始化基础参数** @param builder*/private VerifyUtil(Builder builder) {SIZE = builder.size;LINES = builder.lines;WIDTH = builder.width;HEIGHT = builder.height;FONT_SIZE = builder.fontSize;TILT = builder.tilt;BACKGROUND_COLOR = builder.backgroundColor;}/*** 实例化构造器对象** @return*/public static Builder newBuilder() {return new Builder();}/*** @description:  仅创建验证码* @date: 2024/12/16 10:50* @param* @return java.lang.Object[]*/public String createCode() {StringBuffer sb = new StringBuffer();// 画随机字符Random ran = new Random();for (int i = 0; i < SIZE; i++) {// 取随机字符索引int n = ran.nextInt(chars.length);// 得到字符文本String code = String.valueOf(chars[n]);// 记录字符
            sb.append(code);}return sb.toString();}/*** @description:  生成随机验证码和base64图片* @date: 2024/12/16 10:53* Object[0]:验证码字符串;* Object[1]:base64验证码图片字符串。* @return java.lang.Object[]*/public Object[] createCodeAndBase64Image() {StringBuffer sb = new StringBuffer();// 创建空白图片BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);// 获取图片画笔Graphics2D graphic = image.createGraphics();// 设置抗锯齿
        graphic.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 设置画笔颜色
        graphic.setColor(BACKGROUND_COLOR);// 绘制矩形背景graphic.fillRect(0, 0, WIDTH, HEIGHT);// 画随机字符Random ran = new Random();//graphic.setBackground(Color.WHITE);// 计算每个字符占的宽度,这里预留一个字符的位置用于左右边距int codeWidth = WIDTH / (SIZE + 1);// 字符所处的y轴的坐标int y = HEIGHT * 3 / 4;for (int i = 0; i < SIZE; i++) {// 设置随机颜色
            graphic.setColor(getRandomColor());// 初始化字体Font font = new Font(null, Font.BOLD + Font.ITALIC, FONT_SIZE);if (TILT) {// 随机一个倾斜的角度 -45到45度之间int theta = ran.nextInt(45);// 随机一个倾斜方向 左或者右theta = (ran.nextBoolean() == true) ? theta : -theta;AffineTransform affineTransform = new AffineTransform();affineTransform.rotate(Math.toRadians(theta), 0, 0);font = font.deriveFont(affineTransform);}// 设置字体大小
            graphic.setFont(font);// 计算当前字符绘制的X轴坐标int x = (i * codeWidth) + (codeWidth / 2);// 取随机字符索引int n = ran.nextInt(chars.length);// 得到字符文本String code = String.valueOf(chars[n]);// 画字符
            graphic.drawString(code, x, y);// 记录字符
            sb.append(code);}// 画干扰线for (int i = 0; i < LINES; i++) {// 设置随机颜色
            graphic.setColor(getRandomColor());// 随机画线
            graphic.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT), ran.nextInt(WIDTH), ran.nextInt(HEIGHT));}// 返回验证码和base64图片ByteArrayOutputStream baos = null;try {baos = new ByteArrayOutputStream();ImageIO.write(image, 'png', baos);} catch (IOException e) {throw new RuntimeException(e);}byte[] bytes = baos.toByteArray();String base64Image = BASE64_IMAGE_PERFIX + Base64.getEncoder().encodeToString(bytes);return new Object[]{sb.toString(), base64Image};}/*** @description:  生成随机验证码和图片* @date: 2024/12/16 10:53* Object[0]:验证码字符串;* Object[1]:验证码图片。*/public Object[] createCodeAndImage() {StringBuffer sb = new StringBuffer();// 创建空白图片BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);// 获取图片画笔Graphics2D graphic = image.createGraphics();// 设置抗锯齿
        graphic.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 设置画笔颜色
        graphic.setColor(BACKGROUND_COLOR);// 绘制矩形背景graphic.fillRect(0, 0, WIDTH, HEIGHT);// 画随机字符Random ran = new Random();//graphic.setBackground(Color.WHITE);// 计算每个字符占的宽度,这里预留一个字符的位置用于左右边距int codeWidth = WIDTH / (SIZE + 1);// 字符所处的y轴的坐标int y = HEIGHT * 3 / 4;for (int i = 0; i < SIZE; i++) {// 设置随机颜色
            graphic.setColor(getRandomColor());// 初始化字体Font font = new Font(null, Font.BOLD + Font.ITALIC, FONT_SIZE);if (TILT) {// 随机一个倾斜的角度 -45到45度之间int theta = ran.nextInt(45);// 随机一个倾斜方向 左或者右theta = (ran.nextBoolean() == true) ? theta : -theta;AffineTransform affineTransform = new AffineTransform();affineTransform.rotate(Math.toRadians(theta), 0, 0);font = font.deriveFont(affineTransform);}// 设置字体大小
            graphic.setFont(font);// 计算当前字符绘制的X轴坐标int x = (i * codeWidth) + (codeWidth / 2);// 取随机字符索引int n = ran.nextInt(chars.length);// 得到字符文本String code = String.valueOf(chars[n]);// 画字符
            graphic.drawString(code, x, y);// 记录字符
            sb.append(code);}// 画干扰线for (int i = 0; i < LINES; i++) {// 设置随机颜色
            graphic.setColor(getRandomColor());// 随机画线
            graphic.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT), ran.nextInt(WIDTH), ran.nextInt(HEIGHT));}// 返回验证码和图片return new Object[]{sb.toString(), image};}/*** 随机取色*/private Color getRandomColor() {Random ran = new Random();Color color = new Color(ran.nextInt(256), ran.nextInt(256), ran.nextInt(256));return color;}/*** 构造器对象*/public static class Builder {// 默认字符数量private int size = 4;// 默认干扰线数量private int lines = 10;// 默认宽度private int width = 80;// 默认高度private int height = 35;// 默认字体大小private int fontSize = 25;// 默认字体倾斜private boolean tilt = true;//背景颜色private Color backgroundColor = Color.LIGHT_GRAY;public Builder setSize(int size) {this.size = size;return this;}public Builder setLines(int lines) {this.lines = lines;return this;}public Builder setWidth(int width) {this.width = width;return this;}public Builder setHeight(int height) {this.height = height;return this;}public Builder setFontSize(int fontSize) {this.fontSize = fontSize;return this;}public Builder setTilt(boolean tilt) {this.tilt = tilt;return this;}public Builder setBackgroundColor(Color backgroundColor) {this.backgroundColor = backgroundColor;return this;}public VerifyUtil build() {return new VerifyUtil(this);}}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/862261.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Java]代理模式

本篇文章主要是对静态代理和动态代理实现思路的简述,以示例为主,少涉及理论。 如果文中阐述不全或不对的,多多交流。【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://www.cnblogs.com/cnb-yuchen/p/18002823 出自【进步*于辰的博客】参考笔记一…

lvs+dr+httpd+keepalived高可用部署

lvs+dr+httpd+keepalived高可用部署参考文档:http://blog.csdn.net/m582445672/article/details/7670015 a、 keepalived 是lvs 的扩展项目,因此它们之间具备良好的兼容性。这点应该是keepalived 部署比其他类似工具能更简洁的原因吧! b、 通过对服务器池对象的健康检查,实…

《数字经济:行业产业链》全景梳理及区域热力图

行业主要上市公司:中兴通讯(000063)、大华股份(002236)、中科创达(300496)、软通动力(301236)、奇安信(688561)、同方股份(600100)、……等 本文核心数据:《数字经济:产业链 》、《数字经济:产业链 - 生态图谱》、《“产业数字化” 和 “数字产业化” 上市公司…

《数字经济行业产业链》全景梳理及区域热力图

行业主要上市公司:中兴通讯(000063)、大华股份(002236)、中科创达(300496)、软通动力(301236)、奇安信(688561)、同方股份(600100)、……等 本文核心数据:《数字经济产业链 》、《数字经济产业链生态图谱》、《产业数字化 和 数字产业化上市公司区域分布 TOP5》、…

【长路经】C#读取文件抛出FileNotFoundException异常

前言 在winform中读取文件信息时,突然抛出了FileNotFoundException的异常,但是本地是有这个文件的。 随后找到了这个文件,查看属性,[位置]属性,多了"\\?\"的前缀,百度得知这是windows对长路经的处理。需要注意: 目前在NetFx框架下,才有这个问题。 在NetCore…

【unity】学习制作类银河恶魔城游戏-5-

在-1---4-中,了解了unity的基础操作,从创建一个人物开始,通过状态机和代码完善人物的各种功能达到预期效果,随着功能的越来越多,状态机的处理也就越发麻烦,因此,从零开始设计一个合理的状态机很有必要 梦开始的地方 创建一个新的项目修改舒服的布局创建状态机,通过脚本…

CH340C 请求 USB 设备描述符失败

简短不看版如果出现上述状况,说明线有问题:线的确是数据线(不是电源线),但是不是能与CH340正常通讯的数据线(数据线的数据传输功能有问题。 需要更换其它数据线.前文该文分享CH340驱动使用过程可能出现的问题,以下出现的问题解决方案都建立在CH340硬件正常的情况下。CH3…

CH32V203F6P6-TSSOP20测试之02

一、问题思考 直接用官方提供的例程,为何下载程序后没有什么响应,难道自己设计的电路有什么不妥? 于是,对于电路进行具体分析,结果发现: 第一、官方的BOOT0采用杜邦线连接,在芯片手册好像找不到关于BOOT0的叙述,仅仅在《CH32V20x评估板说明书》中看到:也就是说,这芯片…

PVC

短线反弹

大语言模型提示技巧(一)-指令要清晰、具体

在与大语言模型对话时,应该提供尽可能清晰和具体的指令来表达希望模型执行的操作,这将有助于模型给出接近你所期待的输出,并降低得到无关或不正确回复的可能性。但需要注意的是,编写清晰的指令不意味着编写简短的指令,事实上,更长的提示实际上更清晰且提供了更多的上下文…

再见2024,一个算法研发的个人年终总结

元旦将近,显然又是一年岁末。 同事开始讨论中午吃什么,以及晚上的跨年计划之类的大问题。 我开始努力回想自己的2024,秉承着毕业以来每年写个人总结的习惯, 也因为近年来自己的节奏和生活越来越快,只能在年终的节点停下来回顾下自己的历程。 前言 我打开了自己的相册,下面…

; 自动设置电脑快捷键的AutoHotkey脚本程序源代码 2025年1月1日

; 自动设置电脑快捷键的AutoHotkey脚本程序源代码 2025年1月1日 ; 自动设置电脑快捷键的AutoHotkey脚本程序源代码 2025年1月1日;======== 设置显示或者隐藏MasterSeeker和Total Commander主窗口的快捷键的AutoHotkey脚本2024.10.21 ========= ; 此脚本从此行开始 ; D:\app\Re…