|
1
|
-package com.ruoyi.common.utils;
|
|
|
|
2
|
-
|
|
|
|
3
|
-import java.awt.Color;
|
|
|
|
4
|
-import java.awt.Font;
|
|
|
|
5
|
-import java.awt.Graphics;
|
|
|
|
6
|
-import java.awt.Graphics2D;
|
|
|
|
7
|
-import java.awt.RenderingHints;
|
|
|
|
8
|
-import java.awt.geom.AffineTransform;
|
|
|
|
9
|
-import java.awt.image.BufferedImage;
|
|
|
|
10
|
-import java.io.IOException;
|
|
|
|
11
|
-import java.io.OutputStream;
|
|
|
|
12
|
-import java.security.SecureRandom;
|
|
|
|
13
|
-import java.util.Arrays;
|
|
|
|
14
|
-import java.util.Random;
|
|
|
|
15
|
-import javax.imageio.ImageIO;
|
|
|
|
16
|
-
|
|
|
|
17
|
-/**
|
|
|
|
18
|
- * 验证码工具类
|
|
|
|
19
|
- *
|
|
|
|
20
|
- * @author ruoyi
|
|
|
|
21
|
- */
|
|
|
|
22
|
-public class VerifyCodeUtils
|
|
|
|
23
|
-{
|
|
|
|
24
|
- // 使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
|
|
|
|
25
|
- public static final String VERIFY_CODES = "123456789ABCDEFGHJKLMNPQRSTUVWXYZ";
|
|
|
|
26
|
-
|
|
|
|
27
|
- private static Random random = new SecureRandom();
|
|
|
|
28
|
-
|
|
|
|
29
|
- /**
|
|
|
|
30
|
- * 使用系统默认字符源生成验证码
|
|
|
|
31
|
- *
|
|
|
|
32
|
- * @param verifySize 验证码长度
|
|
|
|
33
|
- * @return
|
|
|
|
34
|
- */
|
|
|
|
35
|
- public static String generateVerifyCode(int verifySize)
|
|
|
|
36
|
- {
|
|
|
|
37
|
- return generateVerifyCode(verifySize, VERIFY_CODES);
|
|
|
|
38
|
- }
|
|
|
|
39
|
-
|
|
|
|
40
|
- /**
|
|
|
|
41
|
- * 使用指定源生成验证码
|
|
|
|
42
|
- *
|
|
|
|
43
|
- * @param verifySize 验证码长度
|
|
|
|
44
|
- * @param sources 验证码字符源
|
|
|
|
45
|
- * @return
|
|
|
|
46
|
- */
|
|
|
|
47
|
- public static String generateVerifyCode(int verifySize, String sources)
|
|
|
|
48
|
- {
|
|
|
|
49
|
- if (sources == null || sources.length() == 0)
|
|
|
|
50
|
- {
|
|
|
|
51
|
- sources = VERIFY_CODES;
|
|
|
|
52
|
- }
|
|
|
|
53
|
- int codesLen = sources.length();
|
|
|
|
54
|
- Random rand = new Random(System.currentTimeMillis());
|
|
|
|
55
|
- StringBuilder verifyCode = new StringBuilder(verifySize);
|
|
|
|
56
|
- for (int i = 0; i < verifySize; i++)
|
|
|
|
57
|
- {
|
|
|
|
58
|
- verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1)));
|
|
|
|
59
|
- }
|
|
|
|
60
|
- return verifyCode.toString();
|
|
|
|
61
|
- }
|
|
|
|
62
|
-
|
|
|
|
63
|
- /**
|
|
|
|
64
|
- * 输出指定验证码图片流
|
|
|
|
65
|
- *
|
|
|
|
66
|
- * @param w
|
|
|
|
67
|
- * @param h
|
|
|
|
68
|
- * @param os
|
|
|
|
69
|
- * @param code
|
|
|
|
70
|
- * @throws IOException
|
|
|
|
71
|
- */
|
|
|
|
72
|
- public static void outputImage(int w, int h, OutputStream os, String code) throws IOException
|
|
|
|
73
|
- {
|
|
|
|
74
|
- int verifySize = code.length();
|
|
|
|
75
|
- BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
|
|
|
76
|
- Random rand = new Random();
|
|
|
|
77
|
- Graphics2D g2 = image.createGraphics();
|
|
|
|
78
|
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
|
|
79
|
- Color[] colors = new Color[5];
|
|
|
|
80
|
- Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN, Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA,
|
|
|
|
81
|
- Color.ORANGE, Color.PINK, Color.YELLOW };
|
|
|
|
82
|
- float[] fractions = new float[colors.length];
|
|
|
|
83
|
- for (int i = 0; i < colors.length; i++)
|
|
|
|
84
|
- {
|
|
|
|
85
|
- colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
|
|
|
|
86
|
- fractions[i] = rand.nextFloat();
|
|
|
|
87
|
- }
|
|
|
|
88
|
- Arrays.sort(fractions);
|
|
|
|
89
|
-
|
|
|
|
90
|
- g2.setColor(Color.GRAY);// 设置边框色
|
|
|
|
91
|
- g2.fillRect(0, 0, w, h);
|
|
|
|
92
|
-
|
|
|
|
93
|
- Color c = getRandColor(200, 250);
|
|
|
|
94
|
- g2.setColor(c);// 设置背景色
|
|
|
|
95
|
- g2.fillRect(0, 2, w, h - 4);
|
|
|
|
96
|
-
|
|
|
|
97
|
- // 绘制干扰线
|
|
|
|
98
|
- Random random = new Random();
|
|
|
|
99
|
- g2.setColor(getRandColor(160, 200));// 设置线条的颜色
|
|
|
|
100
|
- for (int i = 0; i < 20; i++)
|
|
|
|
101
|
- {
|
|
|
|
102
|
- int x = random.nextInt(w - 1);
|
|
|
|
103
|
- int y = random.nextInt(h - 1);
|
|
|
|
104
|
- int xl = random.nextInt(6) + 1;
|
|
|
|
105
|
- int yl = random.nextInt(12) + 1;
|
|
|
|
106
|
- g2.drawLine(x, y, x + xl + 40, y + yl + 20);
|
|
|
|
107
|
- }
|
|
|
|
108
|
-
|
|
|
|
109
|
- // 添加噪点
|
|
|
|
110
|
- float yawpRate = 0.05f;// 噪声率
|
|
|
|
111
|
- int area = (int) (yawpRate * w * h);
|
|
|
|
112
|
- for (int i = 0; i < area; i++)
|
|
|
|
113
|
- {
|
|
|
|
114
|
- int x = random.nextInt(w);
|
|
|
|
115
|
- int y = random.nextInt(h);
|
|
|
|
116
|
- int rgb = getRandomIntColor();
|
|
|
|
117
|
- image.setRGB(x, y, rgb);
|
|
|
|
118
|
- }
|
|
|
|
119
|
-
|
|
|
|
120
|
- shear(g2, w, h, c);// 使图片扭曲
|
|
|
|
121
|
-
|
|
|
|
122
|
- g2.setColor(getRandColor(100, 160));
|
|
|
|
123
|
- int fontSize = h - 4;
|
|
|
|
124
|
- Font font = new Font("Algerian", Font.ITALIC, fontSize);
|
|
|
|
125
|
- g2.setFont(font);
|
|
|
|
126
|
- char[] chars = code.toCharArray();
|
|
|
|
127
|
- for (int i = 0; i < verifySize; i++)
|
|
|
|
128
|
- {
|
|
|
|
129
|
- AffineTransform affine = new AffineTransform();
|
|
|
|
130
|
- affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1),
|
|
|
|
131
|
- (w / verifySize) * i + fontSize / 2, h / 2);
|
|
|
|
132
|
- g2.setTransform(affine);
|
|
|
|
133
|
- g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10);
|
|
|
|
134
|
- }
|
|
|
|
135
|
-
|
|
|
|
136
|
- g2.dispose();
|
|
|
|
137
|
- ImageIO.write(image, "jpg", os);
|
|
|
|
138
|
- }
|
|
|
|
139
|
-
|
|
|
|
140
|
- private static Color getRandColor(int fc, int bc)
|
|
|
|
141
|
- {
|
|
|
|
142
|
- if (fc > 255) {
|
|
|
|
143
|
- fc = 255;
|
|
|
|
144
|
- }
|
|
|
|
145
|
- if (bc > 255) {
|
|
|
|
146
|
- bc = 255;
|
|
|
|
147
|
- }
|
|
|
|
148
|
- int r = fc + random.nextInt(bc - fc);
|
|
|
|
149
|
- int g = fc + random.nextInt(bc - fc);
|
|
|
|
150
|
- int b = fc + random.nextInt(bc - fc);
|
|
|
|
151
|
- return new Color(r, g, b);
|
|
|
|
152
|
- }
|
|
|
|
153
|
-
|
|
|
|
154
|
- private static int getRandomIntColor()
|
|
|
|
155
|
- {
|
|
|
|
156
|
- int[] rgb = getRandomRgb();
|
|
|
|
157
|
- int color = 0;
|
|
|
|
158
|
- for (int c : rgb)
|
|
|
|
159
|
- {
|
|
|
|
160
|
- color = color << 8;
|
|
|
|
161
|
- color = color | c;
|
|
|
|
162
|
- }
|
|
|
|
163
|
- return color;
|
|
|
|
164
|
- }
|
|
|
|
165
|
-
|
|
|
|
166
|
- private static int[] getRandomRgb()
|
|
|
|
167
|
- {
|
|
|
|
168
|
- int[] rgb = new int[3];
|
|
|
|
169
|
- for (int i = 0; i < 3; i++)
|
|
|
|
170
|
- {
|
|
|
|
171
|
- rgb[i] = random.nextInt(255);
|
|
|
|
172
|
- }
|
|
|
|
173
|
- return rgb;
|
|
|
|
174
|
- }
|
|
|
|
175
|
-
|
|
|
|
176
|
- private static void shear(Graphics g, int w1, int h1, Color color)
|
|
|
|
177
|
- {
|
|
|
|
178
|
- shearX(g, w1, h1, color);
|
|
|
|
179
|
- shearY(g, w1, h1, color);
|
|
|
|
180
|
- }
|
|
|
|
181
|
-
|
|
|
|
182
|
- private static void shearX(Graphics g, int w1, int h1, Color color)
|
|
|
|
183
|
- {
|
|
|
|
184
|
-
|
|
|
|
185
|
- int period = random.nextInt(2);
|
|
|
|
186
|
-
|
|
|
|
187
|
- boolean borderGap = true;
|
|
|
|
188
|
- int frames = 1;
|
|
|
|
189
|
- int phase = random.nextInt(2);
|
|
|
|
190
|
-
|
|
|
|
191
|
- for (int i = 0; i < h1; i++)
|
|
|
|
192
|
- {
|
|
|
|
193
|
- double d = (double) (period >> 1)
|
|
|
|
194
|
- * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);
|
|
|
|
195
|
- g.copyArea(0, i, w1, 1, (int) d, 0);
|
|
|
|
196
|
- if (borderGap)
|
|
|
|
197
|
- {
|
|
|
|
198
|
- g.setColor(color);
|
|
|
|
199
|
- g.drawLine((int) d, i, 0, i);
|
|
|
|
200
|
- g.drawLine((int) d + w1, i, w1, i);
|
|
|
|
201
|
- }
|
|
|
|
202
|
- }
|
|
|
|
203
|
-
|
|
|
|
204
|
- }
|
|
|
|
205
|
-
|
|
|
|
206
|
- private static void shearY(Graphics g, int w1, int h1, Color color)
|
|
|
|
207
|
- {
|
|
|
|
208
|
-
|
|
|
|
209
|
- int period = random.nextInt(40) + 10; // 50;
|
|
|
|
210
|
-
|
|
|
|
211
|
- int frames = 20;
|
|
|
|
212
|
- int phase = 7;
|
|
|
|
213
|
- for (int i = 0; i < w1; i++)
|
|
|
|
214
|
- {
|
|
|
|
215
|
- double d = (double) (period >> 1)
|
|
|
|
216
|
- * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);
|
|
|
|
217
|
- g.copyArea(i, 0, 1, h1, 0, (int) d);
|
|
|
|
218
|
- g.setColor(color);
|
|
|
|
219
|
- g.drawLine(i, (int) d, i, 0);
|
|
|
|
220
|
- g.drawLine(i, (int) d + h1, i, h1);
|
|
|
|
221
|
- }
|
|
|
|
222
|
- }
|
|
|
|
223
|
-} |
|
|