算数验证码,字符验证码
算数运算验证码
这是基于springboot的环境写的类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
/**
* @title 验证码
* @description
* @author admin Dshzs17
* @updateTime 2022/3/7 18:26
* @throws
*/
@Controller
public class NumberCaptcha {
// 宽度
private static final int IMAGE_WIDTH = 160;
// 高度
private static final int IMAGE_HEIGHT = 40;
// 字体大小
private static final int FONT_SIZE = 28;
private static final Random RANDOM = new Random();
// 计算公式
private String content;
// 计算结果
private int result;
/**
* 生成随机验证码
*/
private void createMathChar() {
StringBuilder number = new StringBuilder();
int xx = RANDOM.nextInt(10);
int yy = RANDOM.nextInt(10);
// 0~3 对应加减乘除
int round = (int) Math.round(Math.random() * 3);
if (round == 0) {
this.result = yy + xx;
number.append(yy);
number.append("+");
number.append(xx);
} else if (round == 1) {
this.result = yy - xx;
number.append(yy);
number.append("-");
number.append(xx);
} else if (round == 2) {
this.result = yy * xx;
number.append(yy);
number.append("x");
number.append(xx);
} else {
// 0不可为被除数 yy对xx取余无余数
if (!(xx == 0) && yy % xx == 0) {
this.result = yy / xx;
number.append(yy);
number.append("/");
number.append(xx);
} else {
this.result = yy + xx;
number.append(yy);
number.append("+");
number.append(xx);
}
}
content = number.append("=?").toString();
System.out.println(content);
}
// 获取随机颜色
private Color color() {
int r = RANDOM.nextInt(256);
int g = RANDOM.nextInt(256);
int b = RANDOM.nextInt(256);
return new Color(r, g, b);
}
/**
* 随机画干扰圆
*
* @param num 数量
* @param g Graphics2D
*/
private void drawOval(int num, Graphics2D g) {
for (int i = 0; i < num; i++) {
g.setColor(color());
int j = 5 + RANDOM.nextInt(10);
g.drawOval(RANDOM.nextInt(IMAGE_WIDTH - 25), RANDOM.nextInt(IMAGE_HEIGHT - 15), j, j);
}
}
/**
* 定义字体
* @return
*/
private Font font() {
Font font = new Font("宋体",Font.BOLD,FONT_SIZE);
return font;
}
/**
* 生成验证码图形
*/
public BufferedImage create() {
createMathChar();
char[] chars = content.toCharArray();
BufferedImage image = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D) image.getGraphics();
// 填充背景
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
// 抗锯齿
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 画干扰圆
drawOval(2, g2d);
// 画字符串
g2d.setFont(font());
FontMetrics fontMetrics = g2d.getFontMetrics();
// 每一个字符所占的宽度
int fx = IMAGE_WIDTH / chars.length;
// 字符左填充
int flp = 10;
for (int i = 0; i < chars.length; i++) {
String item = String.valueOf(chars[i]);
g2d.setColor(color());
// 文字的纵坐标
int fy = IMAGE_HEIGHT - ((IMAGE_HEIGHT - (int) fontMetrics
.getStringBounds(item, g2d).getHeight()) >> 1);
g2d.drawString(item, flp + i * fx + 3, fy - 3);
}
g2d.dispose();
return image;
}
public String content() {
return content;
}
public int result() {
return result;
}
//调用的类
@GetMapping("/code")
public void code(HttpServletResponse resp) throws IOException {
// 图片类型
String IMAGE_TYPE = "jpg";
NumberCaptcha numberCaptcha = new NumberCaptcha();
BufferedImage image = numberCaptcha.create();
OutputStream ops =resp.getOutputStream();
ImageIO.write(image, IMAGE_TYPE, ops);
ops.close();
}
}
如果想单纯的测试的话就把下面的code方法给删了,然后再测试中建一个测试方法,将这个类注入到测试中,然后调用生成的content()和result()
@Autowired
private NumberCaptcha numberCaptcha;
@Test
void codeTest() throws IOException {
// 图片类型
String IMAGE_TYPE = "jpg";
BufferedImage image = numberCaptcha.create();
ImageIO.write(image, IMAGE_TYPE, new File("D:/data/b" + ".jpg"));
System.out.println(numberCaptcha.content() + ' ' + numberCaptcha.result());
}
字符验证码,也是基于spring写的
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import redis.clients.jedis.Jedis;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
@Controller
public class CodeController {
@RequestMapping("/code")
public void code(HttpServletResponse resp) throws IOException {
/**
* 通过Java代码绘制图片
* 1.图片
* 2.字符
* 3.干扰线
* 4.返回图片
* swing
*/
//创建空白图片
BufferedImage image = new BufferedImage(80, 30, BufferedImage.TYPE_INT_RGB);
//1.获取图片画笔
Graphics g = image.getGraphics();
//随机数
Random r = new Random();
// r.nextInt(255);
// r.nextInt(255),随机数在0到255之间 而且必须是整数 0-1之间的小数
//2.设置画笔颜色
// 设置背景颜色,RGB 三个参数
g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
//3. .绘制矩形的背景
g.fillRect(0, 0, 80, 30);
//4.调用自定义的方法,获取长度为5的字母数字组合的字符串
String number = getNumber(5);
//System.out.println(number);
//将验证码存入session,就是为了判断登录时的验证码是否正确
req.getSession().setAttribute("code", number);
g.setColor(new Color(0, 0, 0));
g.setFont(new Font("宋体", Font.BOLD, 24));
//5.设置颜色字体后,绘制字符串
g.drawString(number, 5, 20);
//6.绘制18条干扰线
for (int i = 0; i < 18; i++) {
g.setColor(new
Color(r.nextInt(255), r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g.drawLine(r.nextInt(100),
r.nextInt(30),
r.nextInt(100),
r.nextInt(30));
// 直线参数 (a,b,x,y),a,b代表起点,x,y代表终点
}
resp.setContentType("image/jpeg");
OutputStream ops = resp.getOutputStream();
ImageIO.write(image, "jpeg", ops);
ops.close();
}
/**
* 字符串的拼接
*
* @param size
* @return
*/
private String getNumber(int size) {
// 1.随机整数 5
// 2.+
// 3.随机整数 3
// =
// 4.?
String str = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890";
// str.charAt(7);通过字符串下标得到对应的字符
StringBuilder number = new StringBuilder();
Random r = new Random();
for (int i = 0; i < size; i++) {
int leng = str.length();//得到字符串的长度
// int suiji = r.nextInt();//随机数0-1之间,
int le = r.nextInt(leng);//得到str的长度之间的随机数
char ss = str.charAt(le);//根据charAt的下标的值,得到str对应的字符
// 需要对字符进行拼接
number.append(ss);
// str.charAt 拿到下标为0-str长度之间的下标,下标从0开始
// number += str.charAt(r.nextInt(str.length()));
}
return number.toString();
}
}