图形验证码应该满足如下要求:
A. 图形验证码里的字符并添加干扰线。
B. 图形验证码应该动态生成,不重复,以防止根据图片hash进行内容匹配。
C. 必须是一次性的,每次验证之后必须更新。
D. 图形验证码对应的字符内容只能在服务端保存。
E. 多样化的图形验证码只要具备安全特性,都可使用。
String num = "4";
int charNum = 4; // 随机产生字符数量
if(num !=null){
charNum = Integer.parseInt(num);
}
int width = 74; // 图片宽
int height = 30; // 图片高
int lineSize = 100; // 干扰线数量
String randString = ""; //需要绘制的随机字符串
BufferedImage buffImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR); // BufferedImage类描述具有可访问图像数据缓冲区的Image
Graphics2D g = buffImage.createGraphics();
//设置背景色
g.setColor(Color.white);
g.fillRect(0,0,width,height);
//设置字体
g.setFont(new Font("Times New Roman",Font.ROMAN_BASELINE, 18));
//画边框
g.drawRect(0,0,width-1,height-1);
//绘制干扰线
Random random = new Random();
for(int i = 0;i <=lineSize;i++)
{
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(width / 8);
int yl = random.nextInt(height / 8);
g.setColor(randColor(130, 250));
g.drawLine(x, y, x + xl, y + yl);
}
//字符集,从中随机产生字符串
char[] characterSet = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'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'};
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.6f)); //设置透明色
g.setFont(new Font("Fixedsys",Font.CENTER_BASELINE, 24));
//产生随机验证码
for(int i = 1;i <=charNum; i++)
{
g.setColor(randColor(20, 130));
String rand = String.valueOf(characterSet[random.nextInt(characterSet.length)]); //获取随机的字符
g.translate(random.nextInt(3), random.nextInt(3));
g.drawString(rand, width / (charNum + 2) * i, height / 4 * 3);
randString += rand;
}
g.dispose();
System.out.println("验证码:"+randString);
session.setAttribute("validateCode",randString);
//禁止图像缓存。
response.setHeader("Pragma","no-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires",0);
OutputStream os = response.getOutputStream();
try{
ImageIO.write(buffImage, "png", os);
os.close();
out.clear();
out = pageContext.pushBody();
}catch(IOException e){
e.printStackTrace();
}
/*
* 随机获取颜色
*/
private Color randColor(int fc, int bc) {
Random random = new Random();
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);
}