JAVA生成安全性高的验证码图片

本文介绍了一种使用Java生成验证码图片的方法,包括如何设置图片大小、字体样式、颜色等,并通过随机函数增加图片的复杂度,如添加混淆线和随机文字。

转自:https://blog.csdn.net/pengzhistar/article/details/53763140

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
import java.util.UUID;

import javax.imageio.ImageIO;

/**
* 功能描述:
*
* @author 彭志(pengzhistar@sina.com.cn)
*
*

修改历史:(修改人,修改时间,修改原因/内容)


*/
public class DrawIdentifyImgUtil {

final static String[] key = new String[]{“1”,”2”,”3”,”4”,”5”,”6”,”7”,”8”,”9”,”0”,”A”,”B”,”C”,”D”,”E”,”F”,”G”,”H”,”I”,”J”,”K”,”L”,”M”,”N”,”O”,”P”,”Q”,”R”,”S”,”T”,”U”,”V”,”W”,”X”,”Y”,”Z”};
static Random random = new Random();

private int width = 0;
private int height = 50;
public void setHeight(int height) {
this.height = height;
}
BufferedImage image = null;

public static String genCodeStr(int length){

StringBuffer buffer = new StringBuffer();
for (int i = 0; i < length; i++) {
buffer.append(key[random.nextInt(key.length)]) ;
}
return buffer.toString();
}

public BufferedImage drawImg(String codeStr){
this.width = 38 * codeStr.length();
image = new BufferedImage(width, height,BufferedImage.TYPE_4BYTE_ABGR_PRE);
Graphics2D g = image.createGraphics();
// 绘制背景
// g.setColor(getRandomColor(200, 250));

//透明度设置
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f));
g.fillRect(0, 0, width, height);
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));

//混淆线
// drawRandomLines(g, 120);
//混淆文字
drawRandomText(g);
//干扰线
drawCenterLine(g);

StringBuffer strbuf = new StringBuffer();
// 定义字体样式
Font myFont = new Font(“Consolas”, Font.BOLD, 38);
boolean b = random.nextBoolean();
for (int i = 0; i < codeStr.length(); i++) {
String temp = String.valueOf(codeStr.charAt(i));
Color color = new Color(40 + random.nextInt(80), 40 + random.nextInt(80), 40 + random.nextInt(80));
g.setColor(color);
//旋转一定的角度
AffineTransform trans = new AffineTransform();
int rad = random.nextInt(30);
if(b = !b){
trans.rotate(Math.toRadians(rad),50 * (i) + 8, 30);
}else{
trans.rotate(Math.toRadians(-rad), 50 * (i) + 8 ,40);
}
// 缩放文字
float scaleSize = random.nextFloat() + 0.8f;
if (scaleSize > 1f){
scaleSize = 1f;
}
trans.scale(1f, 1f);
g.setTransform(trans);
//写文字
// 设置字体
g.setFont(myFont);
g.drawString(temp, 35 * i + (i == 0 ? 10 : 15), 40);
strbuf.append(temp);
}
g.dispose();
return image;
}

public void genImgFile(String fileFullName) throws FileNotFoundException,IOException {
FileOutputStream os = null;
try {
os = new FileOutputStream(new File(fileFullName));
ImageIO.write(image, “PNG”, os);
} catch (FileNotFoundException e) {
throw e;
} catch (IOException e) {
throw e;
}finally{
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 功能描述:随机颜色
*
* @author 彭志(pengzhistar@sina.com.cn)
*

创建日期 :2015年2月3日 下午4:08:37


*
* @param fc
* @param bc
* @return
*
*

修改历史 :(修改人,修改时间,修改原因/内容)


*/
private Color getRandomColor(int fc, int bc) {
if (fc > 255)
fc = 200;
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);
}
/**
* 功能描述:混淆背景线
*
* @author 彭志(pengzhistar@sina.com.cn)
*

创建日期 :2015年2月3日 下午4:10:08


*
* @param g
* @param nums
*
*

修改历史 :(修改人,修改时间,修改原因/内容)


*/
private void drawRandomLines(Graphics2D g, int nums) {
int x1=0,y1=0;
for (int i = 0; i < nums; i++) {
g.setColor(this.getRandomColor(190, 230));
int x2 = random.nextInt(width);
int y2 = random.nextInt(height);
g.drawLine(x1, y1, x2, y2);
x1 = x2;
y1 = y2;
}
}
/**
* 功能描述:混淆文字
*
* @author 彭志(pengzhistar@sina.com.cn)
*

创建日期 :2015年2月3日 下午4:09:59


*
* @param g
*
*

修改历史 :(修改人,修改时间,修改原因/内容)


*/
private void drawRandomText(Graphics2D g){
Font myFont = new Font(“Consolas”, Font.HANGING_BASELINE, 30);
// 设置字体
g.setFont(myFont);
int max = 8 + random.nextInt(4);
for (int i = 0; i < max; i++) {
g.setColor(this.getRandomColor(170, 220));
String temp = key[random.nextInt(key.length)] ;
g.drawString(temp ,i * 24,random.nextInt(height));
}

}
/**
* 功能描述:中间混淆线
*
* @author 彭志(pengzhistar@sina.com.cn)
*

创建日期 :2015年2月3日 下午4:09:42


*
* @param g
*
*

修改历史 :(修改人,修改时间,修改原因/内容)


*/
private void drawCenterLine(Graphics2D g){
Random random = new Random();
int py = 3 + random.nextInt(6);
int x1 = 0, y1 = height/2 , y2 = height/2-1 ;
boolean minus = true;
for(int i = 0 ;i < width; i ++){
g.setColor(this.getRandomColor(60, 80));
g.drawLine(x1, y1, x1, y2);
x1++;
if(minus ){
y1–;y2–;
}else{
y1++;y2++;
}
if(Math.abs(y1 - height/2) > py){
minus = !minus;
py = 3 + random.nextInt(6);
}
}
}

public static void main(String[] args) {
DrawIdentifyImgUtil idCode = new DrawIdentifyImgUtil();
for (int i = 0; i < 100 ;i++) {
System.out.println(UUID.randomUUID().toString());
String codeStr = idCode.genCodeStr(4);
idCode.drawImg(codeStr);
try {
idCode.genImgFile(“d:\img\”+codeStr+”.png”);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

效果图:

Servlet中使用方式

String checkCode = “1234”;

DrawIdentifyImgUtil draw = new DrawIdentifyImgUtil();
BufferedImage image = draw.drawImg(checkCode);

OutputStream os = null;
try {
os = response.getOutputStream();
ImageIO.write(image, “PNG”, os);
image.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值