求学者

JAVA随机生成验证码(一)

图片验证码原理: 服务器生成包含随机字符的字符串图片发给客户端,客户端提交数据需要填写字符串作为验证。而字符串保存在图片中,机器难以识别,达到防止有人利用程序恶意发送信息的目的。

JAVA随机生成图片

JAVA随机生成图片步骤如下:

  1. 创建图片缓存区 传参为宽高和图片类型

    1
    2
    BufferedImage bi = new
    BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
  2. 获取画笔并绘画

    1
    2
    3
    4
    Graphics g = bi.getGraphics(); //获取画笔
    g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,16));//设置字体
    g.setColor(color);//设置画笔颜色
    g.fillRect(0, 0, width, height); //绘制背景
  3. 输出图片

    1
    ImageIO.write(bi, "JPG", resp.getOutputStream());
JAVA实现验证码实例
servlet生成验证码图片源码
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
package com.javaweb.respones;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class IdentityServlet extends HttpServlet{
// 设置字符
public static final char[] chars="1234567890QWERTYUIOPASDFGHJKLZXCVBNM".toCharArray();
// 设置随机数
public static Random random = new Random();
// 获取4位随机数
public static String getRandomString(){
StringBuffer buffer = new StringBuffer();
int index; //获取随机chars下标
for(int i=0;i<4;i++){
index = random.nextInt(chars.length); //获取随机chars下标
buffer.append(chars[index]);
}
return buffer.toString();
}
// 获取随机颜色
public static Color getRandomColor(){
return new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255));
}
// 返回某颜色的反色
public static Color getReverseColor(Color c){
// 防止反色和原色相近
if(c.getRed()<130&&c.getRed()>125 && c.getBlue()<130&& c.getBlue()>125 &&
c.getGreen()<130&&c.getGreen()>125){
return new Color(255,255,255);
}else{
return new Color(255-c.getRed(),255-c.getGreen(),255-c.getBlue());
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String code = getRandomString(); //获取随机验证码
req.getSession().setAttribute("code", code); //放入Session
int width = 100; //图片宽度
int height = 30; //图片高度
Color color = getRandomColor(); //随机色,用于背景色
Color reverse = getReverseColor(color); //反色,用于前景色
/**
* 生成带字符串的文本图片
*/
// 1.创建图片缓存区 传参为宽高和图片类型
BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
// 2.获取画笔并绘画
Graphics g = bi.getGraphics();
g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,16));//设置字体
g.setColor(color);//设置画笔颜色
g.fillRect(0, 0, width, height); //绘制背景
g.setColor(reverse); //设置画笔颜色
g.drawString(code, 18, 20); //绘制字符
// 设置最多100个噪音点
for(int i=0,n = random.nextInt(100);i<n;i++){
g.drawRect(random.nextInt(width), random.nextInt(height), 1, 1);
}
// 3.输出图片
ImageIO.write(bi, "JPG", resp.getOutputStream());
}
}

生成图片验证码主要应用随机数生成器Random生成随机颜色绘制背景,取反色*绘制字符,并绘制最多100随机位置的噪音点,增加识别难度。

配置XML
1
2
3
4
5
6
7
8
<servlet>
<servlet-name>IdentityServlet</servlet-name>
<servlet-class>com.javaweb.respones.IdentityServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>IdentityServlet</servlet-name>
<url-pattern>/servlet/IdentityServlet</url-pattern>
</servlet-mapping>
html展示页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<head>
<script type="text/javascript">
function reloadImage(){
document.getElementById('btn').disable=true;
document.getElementById('identity').src='servlet/IdentityServlet?time='
+new Date().getTime();
}
</script>
</head>
<body>
<img src = "servlet/IdentityServlet" id="identity" onload="btn.disabled= false;">
<input type="button" value="换个图片" onclick="reloadImage()" id="btn">
</body>
截图展示



下篇介绍利用组件Jcaptcha和Kaptcha生成验证码。