java 比较完美的生成验证码的方案

Posted by 浮生 on 03-06,2020

  记得是网上找的,自己改了一下,数字、+ 和等于都是随机的。

package com.km.studio.miJiao.app.noAuthUrl;

import java.awt.*;
import java.awt.image.BufferedImage;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;


public class CreateImageCode {
    //verification code image width
    private static final int IMG_WIDTH = 146;
    //verification code image height
    private static final int IMG_HEIGHT = 30;
    //The number of interference lines
    private static final int DISTURB_LINE_SIZE = 15;
    //generate a random number
    private static Random random = new Random();
    //result
    private static int result;
    //result random string
    private static String randomString;
    //Chinese Numbers

    //Here, must be java Unicode code
    private static final String CUCUMBERS = "\u96F6\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u4E58\u9664\u52A0\u51CF";
    private static final String NUM_STR = "\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u203b\u002f\u002b\u2796";
    //data operator
    private static final Map<String, Integer> OPMap = new HashMap<>();

    static {
        OPMap.put("*", 10);
        OPMap.put("/", 11);
        OPMap.put("+", 12);
        OPMap.put("-", 13);
    }

    /**
     * The generation of image  verification code
     */
    public static BufferedImage drawVerificationCodeImage() {
        //image
        BufferedImage image = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, BufferedImage.TYPE_INT_RGB);
        //In memory to create a brush
        Graphics g = image.getGraphics();

        g.setColor(Color.WHITE);

        g.fillRect(0, 0, IMG_WIDTH, IMG_HEIGHT);
        //Set the brush color
        g.setColor(getRandomColor(200, 250));
        //image border
        g.drawRect(0, 0, IMG_WIDTH - 2, IMG_HEIGHT - 2);

        //Set disturb line color
        g.setColor(getRandomColor(110, 133));
        //Generate random interference lines
        for (int i = 0; i < DISTURB_LINE_SIZE; i++) {
            drawDisturbLine1(g);
            drawDisturbLine2(g);
        }
        //Generate a random number, set return data
        getRandomMathString();
        StringBuilder log = new StringBuilder();
        //The generated random string used to save the system
        for (int j = 0, k = randomString.length(); j < k; j++) {
            Boolean rd = random();
            String t;
            if (rd) {
                t = CUCUMBERS;
            } else {
                t = NUM_STR;
            }
            int child;
            if (j == 1) {
                child = OPMap.get(String.valueOf(randomString.charAt(j)));
            } else {
                child = Integer.parseInt(String.valueOf(randomString.charAt(j)));

            }
            String ch = String.valueOf(t.charAt(child));
            log.append(ch);
            drawRandomString((Graphics2D) g, ch, j);
        }
        //= ?
        if (random()) {
            drawRandomString((Graphics2D) g, "\u7B49\u4E8E\uFF1F", 3);
            log.append("\u7B49\u4E8E\uFF1F");
        } else {
            drawRandomString((Graphics2D) g, "\u003d\uFF1F", 3);
            log.append("\u003d\uFF1F");
        }
        //Release the brush object
        g.dispose();
        System.out.println(log.toString());
        return image;
    }

    private static Boolean random() {
        int i = new Random().nextInt(2);
        if (i == 0) {
            return Boolean.TRUE;
        } else {
            return Boolean.FALSE;
        }
    }

    /**
     * Get a random string
     */
    private static void getRandomMathString() {
        //Randomly generated number 0 to 10
        int xx = random.nextInt(10);
        int yy = random.nextInt(10);
        //save getRandomString
        StringBuilder suChinese = new StringBuilder();
        //random 0,1,2
        int randomOperands = (int) Math.round(Math.random() * 2);
        //multiplication
        if (randomOperands == 0) {
            result = yy * xx;
            suChinese.append(yy);
            suChinese.append("*");
            suChinese.append(xx);
            //division, divisor cannot be zero, Be divisible
        } else if (randomOperands == 1) {
            if (!(xx == 0) && yy % xx == 0) {
                result = yy / xx;
                suChinese.append(yy);
                suChinese.append("/");
            } else {
                result = yy + xx;
                suChinese.append(yy);
                suChinese.append("+");
            }
            suChinese.append(xx);
            //subtraction
        } else if (randomOperands == 2) {
            result = yy - xx;
            suChinese.append(yy);
            suChinese.append("-");
            suChinese.append(xx);
            //add
        } else {
            result = yy + xx;
            suChinese.append(yy);
            suChinese.append("+");
            suChinese.append(xx);
        }
        randomString = suChinese.toString();
    }

    private static Font getRandomFont() {
        int fontSize = (int) Math.round(Math.random() * 4 + 16);
        return new Font(null, Font.BOLD, fontSize);
    }

    /**
     * Draw a random string
     *
     * @param g Graphics
     * @param i the random number of characters
     */
    private static void drawRandomString(Graphics2D g, String randomVCCH, int i) {
        //Set the string font style
        g.setFont(getRandomFont());
        int rc = random.nextInt(255);
        int gc = random.nextInt(255);
        int bc = random.nextInt(255);
        g.setColor(new Color(rc, gc, bc));

        int x = random.nextInt(3);
        int y = random.nextInt(2);
        g.translate(x, y);

        int degree = new Random().nextInt() % 15;

        g.rotate(degree * Math.PI / 180, 5 + i * 25, 20);

        g.drawString(randomVCCH, 5 + i * 25, 20);
        //Reverse Angle
        g.rotate(-degree * Math.PI / 180, 5 + i * 25, 20);
    }

    /**
     * Draw line interference
     *
     * @param g Graphics
     */
    private static void drawDisturbLine1(Graphics g) {
        int x1 = random.nextInt(IMG_WIDTH);
        int y1 = random.nextInt(IMG_HEIGHT);
        int x2 = random.nextInt(13);
        int y2 = random.nextInt(15);
        g.drawLine(x1, y1, x1 + x2, y1 + y2);
    }

    /**
     * Draw line interference
     *
     * @param g Graphics
     */
    private static void drawDisturbLine2(Graphics g) {
        int x1 = random.nextInt(IMG_WIDTH);
        int y1 = random.nextInt(IMG_HEIGHT);
        int x2 = random.nextInt(13);
        int y2 = random.nextInt(15);
        g.drawLine(x1, y1, x1 - x2, y1 - y2);
    }

    /**
     * For random color
     *
     * @param fc fc
     * @param bc bc
     * @return color random color
     */
    private static Color getRandomColor(int fc, int bc) {
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        //Generate random RGB trichromatic
        int r = fc + random.nextInt(bc - fc - 16);
        int g = fc + random.nextInt(bc - fc - 14);
        int b = fc + random.nextInt(bc - fc - 18);
        return new Color(r, g, b);
    }

    /**
     * result.<br/>
     *
     * @return the result <br/>
     */
    public static int getResult() {
        return result;
    }

}

使用getResult获取答案,效果图