平凡也就两个字: 懒和惰;

成功也就两个字: 苦和勤;

优秀也就两个字: 你和我。

跟着我从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生成图形验证码(算数运算图形验证码 + 随机字符图形验证码)...相关推荐

  1. java 产生随机数_java生成随机数

    packagecom.rd.p2p.common.util;importjava.util.Iterator;importjava.util.LinkedHashSet;importjava.util ...

  2. java给定任意_java生成任意整数随机数(任意指定范围)

    Math.random() jdk1.8文档描述: 1.求:范围为 [ 0 ,352324 ] 之间的随机数.(包括临界值) (int)( Math.random () * ( 352324 +1) ...

  3. java 日期随机数_Java 生成指定时间范围的随机时间、随机中文姓名、随机字符姓名、随机数...

    解决问题: Java生成指定时间范围的随机时间? Java生成随机中文姓名? Java生成随机字符姓名? Java生成随机数? 代码: import java.io.UnsupportedEncodi ...

  4. java 同或_java语言中同或运算的实现

    今天在写程序的时候,突然想起来以前学数字电路的异或运算,同或运算.而在java语言中只找到了异或运算(^),却没有同或运算. 1 0 1 0 1 1 0 0                       ...

  5. Java黑皮书课后题第4章:4.16(随机字符)编写一个程序,使用Math.random()方法显示一个随机的大写字母

    4.16(随机字符)编写一个程序,使用Math.random()方法显示一个随机的大写字母 题目 题目概述 破题 生成随机数 随机数与大写字母之间的转换:ASCII 转化为char型 代码 题目 题目 ...

  6. java生成验证码实例_Java生成验证码功能实例代码

    页面上输入验证码是比较常见的一个功能,实现起来也很简单.给大家写一个简单的生成验证码的示例程序,需要的朋友可以借鉴一下. 闲话少续,直接上代码.代码中的注释很详细. package com.SM_te ...

  7. java 单开程序_java生成jar包并且单进程运行的实例

    java文件打包jar运行 有效步骤: 1.cmd 到当前目录(默认包主类所在目录为例) set classpath = 默认包主类所在目录 2.javac 主类名.java 3.java 主类名 4 ...

  8. java uuid 第三方_JAVA生成短8位UUID

    java 原创,转载需注明. 短8位UUID思想其实借鉴微博短域名的生成方式,但是其重复概率过高,而且每次生成4个,需要随即选取一个. 本算法利用62个可打印字符,通过随机生成32位UUID,由于UU ...

  9. java word插件开发_java生成word的几种方案

    1. Jacob是Java-COM Bridge的缩写,它在Java与微软的COM组件之间构建一座桥梁.使用Jacob自带的DLL动态链接库,并通过JNI的方式实现了在Java平台上对COM程序的调用 ...

最新文章

  1. 图灵四月书讯 ——经典与技术前沿的融合
  2. 针对IT人员的四月热点新书推荐
  3. 获取Moment Js中两个日期之间的小时差异
  4. 一、CSS实现横列布局的方法总结
  5. 马斯克采访:要么死的安然,要么活得绚烂
  6. vue 判断页面加载完成_在Vue+webpack中详细讲解基础配置
  7. 解决eclipse和myeclipse不能编译项目的问题
  8. Servlet读取文件的最好的方式
  9. Linux IPC实践(3) --具名FIFO
  10. Centos命令与Vim命令的学习记录
  11. RabbitMQ-JAVA-ClientAPI示例
  12. 总结Cnblogs支持的常用Markdown语法
  13. 学习BIOS与CMOS区别
  14. BZOJ 1090: [SCOI2003]字符串折叠
  15. 一文教你安全的关闭线程池
  16. 快速搭建自己的人脸识别系统
  17. 今天电脑突然出现问题: 请安装 TCP/IP 协议 错误 10106 【已解决·】
  18. el-amap的使用
  19. 如何取消windows xp开机时的登录界面
  20. QT 程序异常结束,crashed

热门文章

  1. 用c语言程序画圣诞树,【图片】用C语言画一棵“圣诞树”(前方高能,学渣小心避让!)【广西科技大学吧】_百度贴吧...
  2. 使用quagga/zebra的RIP实验
  3. 渣渣渣变渣渣系列(4)
  4. 博士申请 | 香港科技大学(广州)李佳老师招收数据挖掘方向全奖博士生
  5. LSH局部敏感hash-口头解释版
  6. pyLSHash:Python 100行代码实现LSH(Locality Sensitive Hashing)算法
  7. 魔兽自己搭的服务器显示已满,人满为患!《魔兽世界》官方预警: 怀旧服多个服务器已超载...
  8. 外设驱动库开发笔记43:GPIO模拟SPI驱动
  9. 半径为20的圆形面积和周长
  10. Mac VirtualBox安装centos8 ssh访问