100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > java 验证码 算术_java生成图形验证码(算数运算图形验证码 + 随机字符图形验证码)...

java 验证码 算术_java生成图形验证码(算数运算图形验证码 + 随机字符图形验证码)...

时间:2024-07-15 19:57:22

相关推荐

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 mons.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.mon.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();

}

}

如果你有疑问或需要技术支持,关注公众号联系我吧~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。