Java operation verification code

Java operation verification code

Earlier, I wrote a text verification code. Now let's do a slightly more advanced operation verification code. That is, the result obtained through the operation is used as the verification code
directly on the code:

/**
 * 运算验证码
 *
 * @author lc
 * 2020-01-20
 */
@Controller
@RequestMapping("/kaptcha")
public class CalculatorKaptcha {
    private static StringBuilder result = new StringBuilder();

    @RequestMapping("/generatekaptcha")
    public void outputKaptcha(HttpServletResponse response) {
        Map<String, Object> operationMap = new HashMap<>();
        operationMap.clear();
        operationMap = generatorOperationVerificationCode();
        //图片
        BufferedImage bufferedImage2 = (BufferedImage) operationMap.get("verificationCodeImage");
        //生成文字验证码
        String text = (String) operationMap.get("verificationCode");
        System.out.println(text);
        /**
         * 这里用于缓存验证码结果,放缓存类或者redis都可以
         * 这里忽略
         */
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");
        ServletOutputStream sos = null;
        try {
            sos = response.getOutputStream();
            ImageIO.write(bufferedImage2, "jpg", sos);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != sos) {
                try {
                    sos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 生成运算验证码
     *
     * @return 运算验证码
     */
    public Map<String, Object> generatorOperationVerificationCode() {
        //  验证码图片边框宽度
        final int WIDTH = 185;
        //  验证码图片边框高度
        final int HEIGHT = 50;
        //  验证码字体高度
        int FONT_HEIGHT = HEIGHT - 12;
        //  验证码干扰线条数
        int INTERFERENCE_LINE = 4;
        // 字体大小
        int FONT_SIZE = 30;

        Map<String, Object> verificationCodeMap = null;
        Random ran = new Random();

        //  生成透明rgb图片
        BufferedImage bufferedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = bufferedImage.getGraphics();
        /**
         * 1.画验证码底部颜色和大小,和边框颜色设置
         */
        Color color = graphics.getColor();
        //  图片全部填充填充黑色
        graphics.setColor(Color.BLACK);
        graphics.fillRect(0, 0, WIDTH, HEIGHT);
        //  图片填充白色;组成黑色边框的白色图片(从1,1的位置到x轴WIDTH - 2,y轴HEIGHT - 2,
        //都填充为白色,那么只剩边框是黑的了)
        graphics.setColor(Color.white);
        graphics.fillRect(1, 1, WIDTH - 2, HEIGHT - 2);


        /**
         *  2.验证码字符串
         *  获取生成的表达式完整的:27 * 20 = ?@540
         * 再切割
         */
        String text = getText();
        System.out.println(text);
        //  运算表达式
        String operationExpression = text.substring(0, text.lastIndexOf("@") - 1);
        //  计算结果
        String result = text.substring(text.lastIndexOf("@") + 1, text.length());


        /**
         * 3.设置字体大小,30-45之间随机变化
         * 字体颜色:随机颜色
         */
        int size = (ran.nextInt(15) + FONT_SIZE);
        //  设置画笔字体
        Font font = new Font(null, Font.ITALIC, size);
        graphics.setFont(font);
        //  根据系统时间创建随机数对象
        graphics.setColor(getRandomColor());
        //  根据画笔颜色绘制字符
        graphics.drawString(operationExpression, 5, FONT_HEIGHT);

        /**
         *  4. 绘制干扰线
         */
        for (int i = 0; i < INTERFERENCE_LINE; i++) {
            //   随机生成rgb颜色值,并设置画笔颜色
            graphics.setColor(getRandomColor());
            //  设置画笔字体
            Font interference_line_font = new Font("微软雅黑", Font.PLAIN, FONT_HEIGHT);
            graphics.setFont(interference_line_font);
            //设置干扰线的起始
            graphics.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT),
                    ran.nextInt(WIDTH), ran.nextInt(HEIGHT));

        }
        //  恢复画笔颜色
        graphics.setColor(color);
        verificationCodeMap = new HashMap<>();
        verificationCodeMap.put("verificationCodeImage", bufferedImage);
        verificationCodeMap.put("verificationCode", result);
        return verificationCodeMap;

    }

    //获取随机颜色
    private Color getRandomColor() {
        Random ran = new Random();
        Color color = new Color(ran.nextInt(256),
                ran.nextInt(256), ran.nextInt(256));
        return color;
    }
    /**
     * 获取运算验证码
     *
     * @return 运算验证码
     */
    public static String getText() {
        Random random = new Random();
        int x = 0;
        x = random.nextInt(31);
        int y = 0;
        y = random.nextInt(31);
        int operationalRules = random.nextInt(4);
        result = new StringBuilder();

        switch (operationalRules) {
            case 0:
                add(x, y);
                break;
            case 1:
                subtract(x, y);
                break;
            case 2:
                multiply(x, y);
                break;
            case 3:
                divide(x, y);
                break;
        }
        return result.toString();
    }
    /**
     * 加法运算
     *
     * @param x 变量x
     * @param y 变量y
     */
    private static void add(int x, int y) {
        result.append(x);
        result.append(" + ");
        result.append(y);
        result.append(" = ?@");
        result.append(x + y);
    }
    /**
     * 减法运算
     *
     * @param x 变量x
     * @param y 变量y
     */
    private static void subtract(int x, int y) {
    	//取两个数字中最大的
        int max = Math.max(x, y);
        //取两个数字中最小的
        int min = Math.min(x, y);
        result.append(max);
        result.append(" - ");
        result.append(min);
        result.append(" = ?@");
        result.append(max - min);
    }
    /**
     * 乘法运算
     *
     * @param x 变量x
     * @param y 变量y
     */
    private static void multiply(int x, int y) {
        int value = x * y;
        result.append(x);
        result.append(value > 1000 ? " + " : " * ");
        result.append(y);
        result.append(" = ?@");
        result.append(value > 1000 ? x + y : x * y);
    }

    /**
     * 除发运算
     * @param x 变量x
     * @param y 变量y
     */
    private static void divide(int x, int y) {
        int max = Math.max(x, y);
        int min = Math.min(x, y);
        if (min == 0) {
            multiply(max, min);
            //可以整除才有除法(以取余数是否为0作判断是否能整除)
        } else if (max % min == 0) {
            result.append(max);
            result.append("÷");
            result.append(min);
            result.append(" = ?@");
            result.append(max / min);
        } else {
            //不能整除就做减法
            subtract(max, min);
        }
    }
}
Published 67 original articles · Liked12 · Visitors 10,000+

Guess you like

Origin blog.csdn.net/m0_37635053/article/details/104052996