算数验证码,字符验证码

算数运算验证码

  这是基于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();
    }
}

 

posted @ 2022-03-15 17:21  Dshzs月  阅读(226)  评论(0编辑  收藏  举报