zbb378@sohu.com
2024-11-04 b2bad51be3c8d3e78d7f81a19415faeac2d0297c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package com.nova.sankuai.infra.utils;
 
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Random;
 
public final class ImageVerifyCode {
 
    private final Random r = new Random();
    private final int weight = 100, height = 40;
    private String text; // 保存验证码的文本内容
    private final String[] fonts = {"Georgia"};
 
    private Color randomColor() {
        int r = this.r.nextInt(225);
        int g = this.r.nextInt(225);
        int b = this.r.nextInt(225);
        return new Color(r, g, b);
    }
 
    private Font randomFont() {
        int index = r.nextInt(fonts.length);
        String fontName = fonts[index];
        int style = r.nextInt(4);
        int size = r.nextInt(10) + 24;
        return new Font(fontName, style, size);
    }
 
    private char randomChar() {
        String codes = "0123456789"; // abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
        int index = r.nextInt(codes.length());
        return codes.charAt(index);
    }
 
    private void drawLine(BufferedImage image) {
        int num = r.nextInt(10); // 定义干扰线的数量
        Graphics2D g = (Graphics2D) image.getGraphics();
        for (int i = 0; i < num; i++) {
            int x1 = r.nextInt(weight);
            int y1 = r.nextInt(height);
            int x2 = r.nextInt(weight);
            int y2 = r.nextInt(height);
            g.setColor(randomColor());
            g.drawLine(x1, y1, x2, y2);
        }
    }
 
    private BufferedImage createImage() {
        // 创建图片缓冲区
        BufferedImage image = new BufferedImage(weight, height, BufferedImage.TYPE_INT_RGB);
        // 获取画笔
        Graphics2D g = (Graphics2D) image.getGraphics();
        // 设置背景色随机
        // g.setColor(new Color(255, 255, r.nextInt(245) + 10));
        g.setColor(Color.white);
        g.fillRect(0, 0, weight, height);
        // 返回一个图片
        return image;
    }
 
    public BufferedImage getImage() {
        BufferedImage image = createImage();
        Graphics2D g = (Graphics2D) image.getGraphics(); // 获取画笔
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            String s = randomChar() + ""; // 随机生成字符,因为只有画字符串的方法,没有画字符的方法,所以需要将字符变成字符串再画
            sb.append(s); // 添加到StringBuilder里面
            float x = i * 1.0F * weight / 4; // 定义字符的x坐标
            g.setFont(randomFont()); // 设置字体,随机
            g.setColor(randomColor()); // 设置颜色,随机
            g.drawString(s, x, height - 5);
        }
        this.text = sb.toString();
        drawLine(image);
        return image;
    }
 
    public String getEncodedText() {
        return encode(text);
    }
 
    public static String encode(String in) {
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("SHA-256");
            digest.update(in.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(digest.digest());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
 
    public static String image2Base64(BufferedImage image) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        ImageIO.write(image, "png", output);
        return "data:image/png;base64," + Base64.getEncoder().encodeToString(output.toByteArray());
    }
}