1、使用BufferedImage创建验证码的背景图片
2、定义一个字符串形式的数学运算字符串
3、使用ScriptEngine对字符串运算公式进行计算
4、将创建好的验证码运算答案存储到redis中,并将验证码运算公式返回前端页面
5、验证验证码是否正确的时候,将redis中的验证码答案和前端提交的答案进行对比,返回验证结果。每次验证完答案,或者更新了验证码,都需要将redis中的验证码删除或者更新。
public class VerifyCode {
public BufferedImage createVerifyCode(User user, long goodsId) {
if (user == null || goodsId <= 0) {
return null;
}
int width = 80;
int height = 32;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.setColor(new Color(0xDCDCDC));
g.fillRect(0, 0, width, height);
g.setColor(Color.black);
g.drawRect(0, 0, width - 1, height - 1);
Random rdm = new Random();
for (int i = 0; i < 50; i++) {
int x = rdm.nextInt(width);
int y = rdm.nextInt(height);
g.drawOval(x, y, 0, 0);
}
String verifyCode = generateVerifyCode(rdm);
g.setColor(new Color(0, 100, 0));
g.setFont(new Font("Candara", Font.BOLD, 24));
g.drawString(verifyCode, 8, 24);
g.dispose();
int rnd = calc(verifyCode);
redisService.set(MiaoshaKey.getMiaoshaVerifyCode, user.getId()+","+goodsId, rnd);
return image;
}
private static char[] ops = new char[] {'+', '-', '*'};
private String generateVerifyCode(Random rdm) {
int num1 = rdm.nextInt(10);
int num2 = rdm.nextInt(10);
int num3 = rdm.nextInt(10);
char op1 = ops[rdm.nextInt(3)];
char op2 = ops[rdm.nextInt(3)];
return ""+ num1 + op1 + num2 + op2 + num3;
}
private static int calc(String exp) {
try {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
return (Integer)engine.eval(exp);
}catch(Exception e) {
e.printStackTrace();
return 0;
}
}
}