public class VerifyCodeUtils {
//使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ"
private static Random random = new Random()
/**
* 使用系统默认字符源生成验证码
*
* @param verifySize 验证码长度
* @return
*/
public static String generateVerifyCode(int verifySize) {
return generateVerifyCode(verifySize, VERIFY_CODES)
}
/**
* 使用指定源生成验证码
*
* @param verifySize 验证码长度
* @param sources 验证码字符源
* @return
*/
public static String generateVerifyCode(int verifySize, String sources) {
if (sources == null || sources.length() == 0) {
sources = VERIFY_CODES
}
int codesLen = sources.length()
Random rand = new Random(System.currentTimeMillis())
StringBuilder verifyCode = new StringBuilder(verifySize)
for (int i = 0
verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1)))
}
return verifyCode.toString()
}
/**
* 输出指定验证码图片流
*
*/
public static void outputImage(int w, int h, OutputStream os, String code) throws IOException {
int verifySize = code.length()
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB)
Random rand = new Random()
Graphics2D g2 = image.createGraphics()
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
Color[] colors = new Color[5]
Color[] colorSpaces = new Color[]{Color.WHITE, Color.CYAN,
Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,
Color.PINK, Color.YELLOW}
float[] fractions = new float[colors.length]
for (int i = 0
colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)]
fractions[i] = rand.nextFloat()
}
Arrays.sort(fractions)
g2.setColor(Color.GRAY)
g2.fillRect(0, 0, w, h)
Color c = getRandColor(200, 250)
g2.setColor(c)
g2.fillRect(0, 2, w, h - 4)
//绘制干扰线
Random random = new Random()
g2.setColor(getRandColor(160, 200))
for (int i = 0
int x = random.nextInt(w - 1)
int y = random.nextInt(h - 1)
int xl = random.nextInt(6) + 1
int yl = random.nextInt(12) + 1
g2.drawLine(x, y, x + xl + 40, y + yl + 20)
}
// 添加噪点
float yawpRate = 0.05f
int area = (int) (yawpRate * w * h)
for (int i = 0
int x = random.nextInt(w)
int y = random.nextInt(h)
int rgb = getRandomIntColor()
image.setRGB(x, y, rgb)
}
shear(g2, w, h, c)
g2.setColor(getRandColor(100, 160))
int fontSize = h - 4
Font font = new Font("Algerian", Font.ITALIC, fontSize)
g2.setFont(font)
char[] chars = code.toCharArray()
for (int i = 0
AffineTransform affine = new AffineTransform()
affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize / 2, h / 2)
g2.setTransform(affine)
g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10)
}
g2.dispose()
ImageIO.write(image, "jpg", os)
}
private static Color getRandColor(int fc, int bc) {
if (fc > 255)
fc = 255
if (bc > 255)
bc = 255
int r = fc + random.nextInt(bc - fc)
int g = fc + random.nextInt(bc - fc)
int b = fc + random.nextInt(bc - fc)
return new Color(r, g, b)
}
private static int getRandomIntColor() {
int[] rgb = getRandomRgb()
int color = 0
for (int c : rgb) {
color = color << 8
color = color | c
}
return color
}
private static int[] getRandomRgb() {
int[] rgb = new int[3]
for (int i = 0
rgb[i] = random.nextInt(255)
}
return rgb
}
private static void shear(Graphics g, int w1, int h1, Color color) {
shearX(g, w1, h1, color)
shearY(g, w1, h1, color)
}
private static void shearX(Graphics g, int w1, int h1, Color color) {
int period = random.nextInt(2)
boolean borderGap = true
int frames = 1
int phase = random.nextInt(2)
for (int i = 0
double d = (double) (period >> 1)
* Math.sin((double) i / (double) period
+ (6.2831853071795862D * (double) phase)
/ (double) frames)
g.copyArea(0, i, w1, 1, (int) d, 0)
if (borderGap) {
g.setColor(color)
g.drawLine((int) d, i, 0, i)
g.drawLine((int) d + w1, i, w1, i)
}
}
}
private static void shearY(Graphics g, int w1, int h1, Color color) {
int period = random.nextInt(40) + 10
boolean borderGap = true
int frames = 20
int phase = 7
for (int i = 0
double d = (double) (period >> 1)
* Math.sin((double) i / (double) period
+ (6.2831853071795862D * (double) phase)
/ (double) frames)
g.copyArea(i, 0, 1, h1, 0, (int) d)
if (borderGap) {
g.setColor(color)
g.drawLine(i, (int) d, i, 0)
g.drawLine(i, (int) d + h1, i, h1)
}
}
}
/**
* 获取随机验证码及其加密图片
*
*/
public static String verifyCode(int w, int h, int size) throws IOException {
BASE64Encoder encoder = new BASE64Encoder()
String code = generateVerifyCode(size).toLowerCase()
ByteArrayOutputStream data = new ByteArrayOutputStream()
outputImage(w, h, data, code)
return encoder.encode(data.toByteArray())
}
/**
* 获取随机验证码及其加密图片
*
*/
public static String verifyCode(int w, int h, String code) throws IOException {
BASE64Encoder encoder = new BASE64Encoder()
ByteArrayOutputStream data = new ByteArrayOutputStream()
outputImage(w, h, data, code)
return encoder.encode(data.toByteArray())
}
/**
* 获取随机验证码及其加密图片
*
*/
public static ByteArrayOutputStream verifyCodeImg(int w, int h, int size) throws IOException {
BASE64Encoder encoder = new BASE64Encoder()
String code = generateVerifyCode(size).toLowerCase()
ByteArrayOutputStream data = new ByteArrayOutputStream()
outputImage(w, h, data, code)
return data
}
public static void main(String[] args) throws Exception{
//单体项目验证码实现-响应流
/*
String code = generateVerifyCode(4).toLowerCase()
System.out.println(code)
ByteArrayOutputStream data = new ByteArrayOutputStream()
outputImage(100, 20, data, code)
FileOutputStream fileOutputStream = null
try {
fileOutputStream = new FileOutputStream("D:\1.jpg")
fileOutputStream.write(data.toByteArray())
} catch (FileNotFoundException e) {
e.printStackTrace()
} catch (IOException e) {
e.printStackTrace()
}*/
//响应base64编码字符串
//System.out.println(VerifyCode(80, 30, 6))
System.out.println(verifyCode(80, 30, 6))
}
}