java 验证码 算术_java生成图形验证码(算数运算图形验证码 + 随机字符图形验证码)...
平凡也就两个字: 懒和惰;
成功也就两个字: 苦和勤;
优秀也就两个字: 你和我。
跟着我从0学习JAVA、spring全家桶和linux运维等知识,带你从懵懂少年走向人生巅峰,迎娶白富美!
关注微信公众号【IT特靠谱 】,每天都会分享技术心得~
生成图形验证码(算数运算图形验证码 + 随机字符图形验证码)
1 场景
在用户登录、忘记密码、用户注册、修改用户信息....等场景需要对用户进行图形化验证。防止别有用心的人或机器通过接口来进行攻击或恶意操作。
本示例讲解通过java生成两种图形验证码:算数运算的图形验证码和定长随机字符图形验证码!
2 编写代码
2.1 创建生成指定长度的随机字符串工具类
创建生成指定长度的随机字符串工具类:RandomCodeUtil.java,该工具类在之前的博客中讲到过。
import java.util.Random;
/**
* 生成指定长度的随机字符串
*/
public class RandomCodeUtil {
/**
* 生成指定长度的随机字符串(不包含数字0,和字母l、o和i)
*
* @param capacity 验证码长度
*/
public static String genCode(Integer capacity) {
//随机字符集(不包含数字0和字母o、i和l)
String str = "abcdefghjkmnpqrstuvwxyz123456789";
Random rand = new Random();
StringBuilder a = new StringBuilder();
for (int i = 0; i < capacity; i++) {
char c = str.charAt(rand.nextInt(str.length()));
a.append(c);
}
return a.toString();
}
public static void main(String[] args) {
//生产6位长度的随机验证码
System.out.println(RandomCodeUtil.genCode(6));
}
}
2.2 创建图形验证码工具类
创建图形验证码工具类:ImgCodeUtil.java
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
/**
* 生成图形验证码工具类
*/
public class ImgCodeUtil {
/**
* 图片的宽度
*/
private Integer width = 120;
/**
* 图片的高度
*/
private Integer height = 40;
/**
* 验证码干扰线条数
*/
private Integer lineCount = 8;
/**
* 验证码code
*/
private String validateCode = null;
/**
* 验证码图片Buffer
*/
private BufferedImage buffImg = null;
/**
* 构造方法
*/
public ImgCodeUtil(String validateCode) {
this.validateCode = validateCode;
this.createCode();
}
/**
* 构造方法
*/
public ImgCodeUtil(String validateCode, int width, int height) {
this.width = width;
this.height = height;
this.validateCode = validateCode;
this.createCode();
}
/**
* 生成验证码图片
*/
private void createCode() {
int x = 0;
int fontHeight;
int codeY = 0;
int red = 0;
int green = 0;
int blue = 0;
int codeCount = validateCode.length();
//每个字符的宽度
x = width / codeCount;
//字体的高度
fontHeight = height - 2;
codeY = height - 4;
// 图像buffer
buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = buffImg.createGraphics();
// 生成随机数
Random random = new Random();
// 将图像填充为白色
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
//图片划线
for (int i = 0; i < lineCount; i++) {
int xs = random.nextInt(width / 2);
int ys = random.nextInt(height);
int xe = random.nextInt(width / 2) + width / 2;
int ye = random.nextInt(height);
red = random.nextInt(255);
green = random.nextInt(255);
blue = random.nextInt(255);
g.setColor(new Color(red, green, blue));
g.drawLine(xs, ys, xe, ye);
}
Font font = new Font("Arial", Font.BOLD, fontHeight);
g.setFont(font);
// 将验证码写入图片
for (int i = 0; i < codeCount; i++) {
red = random.nextInt(255);
green = random.nextInt(255);
blue = random.nextInt(255);
g.setColor(new Color(red, green, blue));
g.drawString(String.valueOf(validateCode.charAt(i)), i * x, codeY);
}
}
/**
* 输出图片到指定路径
*/
public void write(String path) throws IOException {
OutputStream outputStream = new FileOutputStream(path);
this.write(outputStream);
}
/**
* 将图片输出到输出流中
*/
public void write(OutputStream outputStream) throws IOException {
ImageIO.write(buffImg, "png", outputStream);
outputStream.close();
}
public BufferedImage getBuffImg() {
return buffImg;
}
}
2.3 创建图形验证码接口类
创建图形验证码接口类:ValidateCodeService.java
import com.xxx.alltest.dto.CheckCode;
import com.xxx.alltest.entity.ValidateCode;
/**
* 图形验证码接口类
*/
public interface ValidateCodeService {
/**
* 生成算数运算图形验证码
*/
ValidateCode generateMathImgCode(Integer width, Integer height);
/**
* 生成随机字符串图形验证码
*/
ValidateCode generateRandomImgCode(Integer width, Integer height);
/**
* 校验图形验证码值
*/
String checkValidateCode(CheckCode checkCode);
}
2.4 创建图形验证码接口实现类
图形验证码接口实现类:ValidateCodeServiceImpl.java
import com.xxx.alltest.dto.CheckCode;
import com.xxx.alltest.entity.ValidateCode;
import com.xxx.alltest.service.ValidateCodeService;
import com.xxx.alltest.utils.ImgCodeUtil;
import com.xxx.alltest.utils.RandomCodeUtil;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Objects;
import java.util.UUID;
import javax.imageio.ImageIO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;
/**
* 图形验证码接口实现类
*/
@Slf4j
@Service
public class ValidateCodeServiceImpl implements ValidateCodeService {
/**
* 验证码过期时间:5分钟
*/
private static final Long EXPIRE_TIME = 5 * 60 * 1000L;
/**
* 生成算数运算图形验证码
*/
@Override
public ValidateCode generateMathImgCode(Integer width, Integer height) {
Integer firstNum = RandomUtils.nextInt() % 10 + 1;
Integer secondNum = RandomUtils.nextInt() % 10 + 1;
Integer validateCode = firstNum + secondNum;
ImgCodeUtil imgCodeUtil = new ImgCodeUtil(firstNum + "+" + secondNum + "=?", width, height);
BufferedImage buffImg = imgCodeUtil.getBuffImg();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
String base64ImgCode = null;
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
try {
ImageIO.write(buffImg, "png", byteArrayOutputStream);
byte[] bytes = byteArrayOutputStream.toByteArray();
base64ImgCode = Base64Utils.encodeToString(bytes);
//将生成的验证码缓存起来
// redisTemplate.set(String.join(":", "mathImgCode", uuid), validateCode.toString(), EXPIRE_TIME);
} catch (IOException var10) {
log.error("生成算数运算图形验证码失败");
}
return ValidateCode.builder()
.base64ImgCode(base64ImgCode)
.uuid(uuid)
.build();
}
/**
* 生成随机字符串图形验证码
*/
@Override
public ValidateCode generateRandomImgCode(Integer width, Integer height) {
String validateCode = RandomCodeUtil.genCode(4);
ImgCodeUtil imgCodeUtil = new ImgCodeUtil(validateCode, width, height);
BufferedImage buffImg = imgCodeUtil.getBuffImg();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
String base64ImgCode = null;
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
try {
ImageIO.write(buffImg, "png", byteArrayOutputStream);
byte[] bytes = byteArrayOutputStream.toByteArray();
base64ImgCode = Base64Utils.encodeToString(bytes);
//将生成的验证码缓存起来
// redisTemplate.set(String.join(":", "randomImgCode", uuid), validateCode, EXPIRE_TIME);
} catch (IOException var10) {
log.error("生成随机字符串图形验证码失败");
}
return ValidateCode.builder()
.base64ImgCode(base64ImgCode)
.uuid(uuid)
.build();
}
/**
* 校验图形验证码值
*/
@Override
public String checkValidateCode(CheckCode checkCode) {
String redisCode = null;
// String redisCode = redisTemplate.get(String.join(":", "randomImgCode", checkCode.getUuid()));
if (StringUtils.isEmpty(redisCode)) {
return "验证码已过期";
}
if (!Objects.equals(checkCode.getValidateCode(), redisCode)) {
return "验证码错误";
}
return null;
}
}
2.5 创建验证码相关api接口类
创建验证码相关api接口类:ValidateCodeController.java
import com.xxx.alltest.all.oss.common.Result;
import com.xxx.alltest.dto.CheckCode;
import com.xxx.alltest.entity.ValidateCode;
import com.xxx.alltest.service.ValidateCodeService;
import java.util.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 验证码相关api接口
*/
@RestController
@RequestMapping("/validate")
public class ValidateCodeController {
@Autowired
private ValidateCodeService validateCodeService;
/**
* 生成图形验证码
*
* @param type 0-普通字符图形验证码(如:1a4h) 1-算数图形验证码(1+8=?)
*/
@GetMapping("generate")
public Result generate(@RequestParam(value = "type", defaultValue = "0") String type,
@RequestParam(value = "width", defaultValue = "100") Integer width,
@RequestParam(value = "height", defaultValue = "40") Integer height) {
ValidateCode validateCode = null;
if (Objects.equals("0", type)) {
validateCode = validateCodeService.generateRandomImgCode(width, height);
} else {
validateCode = validateCodeService.generateMathImgCode(width, height);
}
if (StringUtils.isEmpty(validateCode.getBase64ImgCode())) {
return Result.failed("生成图形验证码失败");
} else {
return Result.ok(validateCode);
}
}
/**
* 校验图形验证码
*/
@PostMapping("check")
public Result check(@RequestBody CheckCode checkCode) {
String msg = validateCodeService.checkValidateCode(checkCode);
if (!StringUtils.isEmpty(msg)) {
return Result.failed(msg);
}
return Result.ok();
}
}
如果你有疑问或需要技术支持,关注公众号联系我吧~
java 验证码 算术_java生成图形验证码(算数运算图形验证码 + 随机字符图形验证码)...相关推荐
- java 产生随机数_java生成随机数
packagecom.rd.p2p.common.util;importjava.util.Iterator;importjava.util.LinkedHashSet;importjava.util ...
- java给定任意_java生成任意整数随机数(任意指定范围)
Math.random() jdk1.8文档描述: 1.求:范围为 [ 0 ,352324 ] 之间的随机数.(包括临界值) (int)( Math.random () * ( 352324 +1) ...
- java 日期随机数_Java 生成指定时间范围的随机时间、随机中文姓名、随机字符姓名、随机数...
解决问题: Java生成指定时间范围的随机时间? Java生成随机中文姓名? Java生成随机字符姓名? Java生成随机数? 代码: import java.io.UnsupportedEncodi ...
- java 同或_java语言中同或运算的实现
今天在写程序的时候,突然想起来以前学数字电路的异或运算,同或运算.而在java语言中只找到了异或运算(^),却没有同或运算. 1 0 1 0 1 1 0 0 ...
- Java黑皮书课后题第4章:4.16(随机字符)编写一个程序,使用Math.random()方法显示一个随机的大写字母
4.16(随机字符)编写一个程序,使用Math.random()方法显示一个随机的大写字母 题目 题目概述 破题 生成随机数 随机数与大写字母之间的转换:ASCII 转化为char型 代码 题目 题目 ...
- java生成验证码实例_Java生成验证码功能实例代码
页面上输入验证码是比较常见的一个功能,实现起来也很简单.给大家写一个简单的生成验证码的示例程序,需要的朋友可以借鉴一下. 闲话少续,直接上代码.代码中的注释很详细. package com.SM_te ...
- java 单开程序_java生成jar包并且单进程运行的实例
java文件打包jar运行 有效步骤: 1.cmd 到当前目录(默认包主类所在目录为例) set classpath = 默认包主类所在目录 2.javac 主类名.java 3.java 主类名 4 ...
- java uuid 第三方_JAVA生成短8位UUID
java 原创,转载需注明. 短8位UUID思想其实借鉴微博短域名的生成方式,但是其重复概率过高,而且每次生成4个,需要随即选取一个. 本算法利用62个可打印字符,通过随机生成32位UUID,由于UU ...
- java word插件开发_java生成word的几种方案
1. Jacob是Java-COM Bridge的缩写,它在Java与微软的COM组件之间构建一座桥梁.使用Jacob自带的DLL动态链接库,并通过JNI的方式实现了在Java平台上对COM程序的调用 ...
最新文章
- 图灵四月书讯 ——经典与技术前沿的融合
- 针对IT人员的四月热点新书推荐
- 获取Moment Js中两个日期之间的小时差异
- 一、CSS实现横列布局的方法总结
- 马斯克采访:要么死的安然,要么活得绚烂
- vue 判断页面加载完成_在Vue+webpack中详细讲解基础配置
- 解决eclipse和myeclipse不能编译项目的问题
- Servlet读取文件的最好的方式
- Linux IPC实践(3) --具名FIFO
- Centos命令与Vim命令的学习记录
- RabbitMQ-JAVA-ClientAPI示例
- 总结Cnblogs支持的常用Markdown语法
- 学习BIOS与CMOS区别
- BZOJ 1090: [SCOI2003]字符串折叠
- 一文教你安全的关闭线程池
- 快速搭建自己的人脸识别系统
- 今天电脑突然出现问题: 请安装 TCP/IP 协议 错误 10106 【已解决·】
- el-amap的使用
- 如何取消windows xp开机时的登录界面
- QT 程序异常结束,crashed
热门文章
- 用c语言程序画圣诞树,【图片】用C语言画一棵“圣诞树”(前方高能,学渣小心避让!)【广西科技大学吧】_百度贴吧...
- 使用quagga/zebra的RIP实验
- 渣渣渣变渣渣系列(4)
- 博士申请 | 香港科技大学(广州)李佳老师招收数据挖掘方向全奖博士生
- LSH局部敏感hash-口头解释版
- pyLSHash:Python 100行代码实现LSH(Locality Sensitive Hashing)算法
- 魔兽自己搭的服务器显示已满,人满为患!《魔兽世界》官方预警: 怀旧服多个服务器已超载...
- 外设驱动库开发笔记43:GPIO模拟SPI驱动
- 半径为20的圆形面积和周长
- Mac VirtualBox安装centos8 ssh访问