在如今这个互联网技术十分发达的年代,各种技术层出不穷。各种网站,APP也都应运而生。细看这些网站,APP,都少不了登录和注册这一功能,因为只有注册后登陆了网站或APP才能为各个用户保存属于他们自己的在相应网站,APP上的内容。把焦点集中到注册或登录的实现,不难发现,几乎每一个正规的网站都会有图片验证码这一验证方式,它主要是为了避免非用户人工注册即机器批量恶意注册。而图片验证码的形式也产生了很多种,先前常见的是数字或字母输入验证,还有汉字验证。这些年又出了拖动拼图验证(比如QQ的登录)等等,这篇文章我打算分享的是数字或字母或者汉字输入的验证方式,本文后端的实现使用的是Java的Servlet技术,其他后端语言还需做相应改动,不过相信本质还是一样的。这里先把我做的效果放上。
主要还是放代码吧,一切言语还是没有代码来的实在!
1.实现画想生成的字符的方法
//画汉字
private String drawRandomCh(Graphics2D g) {
String s="";//随机生成的四个字的组合
g.setColor(Color.RED);
g.setFont(new Font("宋体",Font.BOLD,20));
String base="\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6";
//\u4e00-\u9fa5
for(int i=0;i<4;i++){
int degree=new Random().nextInt()%30;
String ch=base.charAt(new Random().nextInt(base.length()))+"";
g.rotate(degree*Math.PI/180, 5+30*i, 20);
g.drawString(ch, 5+30*i, 20);
g.rotate(-degree*Math.PI/180, 5+30*i, 20);
s=s+ch;
}
return s;
}
//画0-9数字
private int drawNum(Graphics2D g) {
int num=0;
String nu="";
g.setColor(Color.RED);
g.setFont(new Font("宋体",Font.BOLD,20));
for(int i=0;i<4;i++){
int degree=new Random().nextInt()%30;
int n=new Random().nextInt(10);
g.rotate(degree*Math.PI/180, 5+30*i, 20);
g.drawString(n+"", 5+30*i, 20);
g.rotate(-degree*Math.PI/180, 5+30*i, 20);
nu=nu+""+n;
}
return Integer.parseInt(nu);
}
//画0-9数字和所有大小写字母
private String drawNums(Graphics2D g) {
String num="";//要返回的字符串
char[] c={'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','A','B','C','D','E','F','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
g.setColor(Color.RED);
g.setFont(new Font("宋体",Font.BOLD,20));
for(int i=0;i<4;i++){
int degree=new Random().nextInt()%30;
int n=new Random().nextInt(c.length);
g.rotate(degree*Math.PI/180, 5+30*i, 20);
g.drawString(c[n]+"", 5+30*i, 20);
g.rotate(-degree*Math.PI/180, 5+30*i, 20);
num=num+c[n];
}
return num;
}
2.画背景,边框,干扰线 的方法
private void setBackground(Graphics g) {
// TODO Auto-generated method stub
g.setColor(Color.BLUE);
g.fillRect(0, 0, WIDTH, HEIGHT);
}
private void setBorder(Graphics g) {
// TODO Auto-generated method stub
g.setColor(Color.WHITE);
g.fillRect(1,1,WIDTH-2,HEIGHT-2);
}
private void drawRandomLine(Graphics g) {
// TODO Auto-generated method stub
g.setColor(Color.GREEN);
for(int i=0;i<5;i++){
int x1=new Random().nextInt(WIDTH);
int y1=new Random().nextInt(HEIGHT);
int x2=new Random().nextInt(WIDTH);
int y2=new Random().nextInt(HEIGHT);
g.drawLine(x1, y1, x2, y2);
}
}
3.在继承了HttpServlet的Servlet的doGet方法(参数有res和req)中添加如下代码
BufferedImage image=new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB);
Graphics g=image.getGraphics();
setBackground(g);//1.设置背景色
setBorder(g);//2.生成边界
drawRandomLine(g);//3.画几条随机干扰线
//String num=drawRandomCh((Graphics2D) g);//4.生成几个随机汉字,需设置编码gbk,不然会抛异常
//num=URLEncoder.encode(num,"gbk");
//int num=drawNum((Graphics2D) g);//随机生成几个数字
String num=drawNums((Graphics2D) g);//随机生成几个数字或字母
//方法1,利用cookie记住验证码
Cookie cookie=new Cookie("code",num+"");
cookie.setMaxAge(60*60);
cookie.setPath("/");
res.addCookie(cookie);
//5.图形写给浏览器
res.setContentType("image/jpeg");
//控制浏览器不要缓存
res.setDateHeader("expries", -1);
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Pragma","no-cache");
ImageIO.write(image, "jpg", res.getOutputStream());
4.最后一步-在你想要输出的jsp中添加以下代码即可显示图片验证码,src后跟设置的Servlet的名,onclick实现点击图片切换图片验证码