注册/登陆界面验证码的作用及代码实现
简介:
验证码的作用:主要是为了有效防止机器恶意注册,对某一个特定已注册用户用特定程序暴力破解方式进行不断的登陆尝试。验证码是现在很多网站注册/登录时必填的,虽然对用户可能有点麻烦,但是对网站/社区来说这个功能还是很有必要,也很重要,不少网站为了防止用户利用机器人自动注册、登录、灌水,都采用了验证码技术。所谓验证码,就是将一串随机产生的数字或符号,生成一幅图片, 图片里加上一些干扰象素(防止OCR),由用户肉眼识别其中的验证码信息,输入表单提交网站验证,验证成功后才能使用某项功能。在这里想要提醒大家要保护自己的密码,尽量使用混杂了数字、字母、符号在内的6位以上密码,不要使用诸如1234之类的简单密码或者与用户名相同、类似的密码。 任何时候在任何地方都不要随意设置密码,保护你自己的密码也是保护你自己,免得你的账号给人盗用给自己带来不必要的麻烦。
常见的验证码:
1.四位数字,随机的一数字字符串,最原始的验证码,验证作用几乎为零。
2.CSDN网站用户登录用的是GIF格式,目前常用的随机数字图片验证码。图片上的字符比较中规中矩,验证作用比上一个好。没有基本图形图像学知识的人,不可破!可惜读取它的程序,在CSDN使用它的第一天,好像就在论坛里发布了。
3.QQ网站用户登录用的是PNG格式,图片用的随机数字+随机大写英文字母,整个构图有点张扬,每刷新一次,每个字符还会变位置呢!有时候出来的图片,人眼都识别不了,厉害啊…
4.MS的hotmail申请时候的是BMP格式, 随机数字+随机大写英文字母+随机干扰像素+随机位置。
5.Google的Gmail注册时候的是JPG格式,随机英文字母+随机颜色+随机位置+随机长度。6,其他各大论坛的是XBM格式,内容随机。
实现代码:
生成验证码图片(dlimage.jsp):
1 <%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" pageEncoding="UTF-8" %> 2 2 <%!Color getRandColor(int fc, int bc) {//给定范围获得随机颜色 3 3 Random random = new Random(); 4 4 if (fc > 255) 5 5 fc = 255; 6 6 if (bc > 255) 7 7 bc = 255; 8 8 int r = fc + random.nextInt(bc - fc); 9 9 int g = fc + random.nextInt(bc - fc); 10 10 int b = fc + random.nextInt(bc - fc); 11 11 return new Color(r, g, b); 12 12 }%> 13 13 <% 14 14 //设置页面不缓存 15 15 response.setHeader("Pragma", "No-cache"); 16 16 response.setHeader("Cache-Control", "no-cache"); 17 17 response.setDateHeader("Expires", 0); 18 18 19 19 // 在内存中创建图象 20 20 int width = 75, height = 32; 21 21 BufferedImage image = new BufferedImage(width, height, 22 22 BufferedImage.TYPE_INT_RGB); 23 23 24 24 // 获取图形上下文 25 25 Graphics g = image.getGraphics(); 26 26 27 27 //生成随机类 28 28 Random random = new Random(); 29 29 30 30 // 设定背景色 31 31 g.setColor(getRandColor(200, 250)); 32 32 g.fillRect(0, 0, width, height); 33 33 34 34 //设定字体 35 35 g.setFont(new Font("Times New Roman", Font.BOLD, 18));//18是设置的字体大小 36 36 37 37 //画边框 38 38 g.setColor(new Color(0, 0, 0)); 39 39 g.drawRect(0, 0, width - 1, height -1);// 细线围成的边框范围 40 40 41 41 // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到 42 42 g.setColor(getRandColor(160, 200)); 43 43 for (int i = 0; i < 155; i++) { 44 44 int x = random.nextInt(width); 45 45 int y = random.nextInt(height); 46 46 int xl = random.nextInt(12); 47 47 int yl = random.nextInt(12); 48 48 g.drawLine(x, y, x + xl, y + yl); 49 49 } 50 50 51 51 // 取随机产生的认证码(4位数字) 52 52 String sRand = ""; 53 53 for (int i = 0; i < 4; i++) { 54 54 String rand = null; 55 55 //随机生成数字或者字母 56 56 if (random.nextInt(10) > 5) { 57 57 rand = String.valueOf((char)(random 58 58 .nextInt(10) + 48)); 59 59 } else { 60 60 rand = String.valueOf((char)(random 61 61 .nextInt(26) + 65)); 62 62 } 63 63 sRand += rand; 64 64 // 将认证码显示到图象中 65 65 g.setColor(new Color(random.nextInt(80), random 66 66 .nextInt(80), random.nextInt(80))); 67 67 //调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成 68 68 g.drawString(rand, 15 * i + 10, 16); 69 69 } 70 70 71 71 // 将认证码存入SESSION 72 72 session.setAttribute("rand", sRand); 73 73 74 74 // 图象生效 75 75 g.dispose(); 76 76 77 77 // 输出图象到页面 78 78 ImageIO.write(image, "JPEG", response.getOutputStream()); 79 79 %>
在注册或登陆页面中引用生成的验证码图片:
<!-- 验证码图片的生成--> <img id="code" src="dlimage.jsp"/> <a href="#" onclick="javascript:var dt=new Date();document.getElementById('code').src='dlimage.jsp?dt='+dt;">
<img alt="看不清,换一张"src="dlimages/1.png"/></a>(*区分字母大小写)
检验验证码输入正确与否:
<%@ page contentType="text/html; charset=utf-8" language="java" import="java.sql.*" errorPage="" %> <html> <head> <title>注册出现问题</title> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache"> <META HTTP-EQUIV="Expires" CONTENT="0"> </head> <body> <% String rand = (String)session.getAttribute("rand");<!-系统随机产生的验证码--> String input = request.getParameter("rand");<!--用户输入的验证码--> if (input.equals(rand)) { %> <!-- 验证码正确的情况下 --> <jsp:forward page="dl.jsp"/> <!-- 此处重定向到的页面可改为登录成功后可进入的页面 --> <%} else {%> 系统产生的验证码为: <%= rand %><br/> 您输入的验证码为: <%= input %><br/>
<!--验证码错误情况下--> 认证失败,请返回登录界面,重新输验证码!<br/> <a href="dl.jsp">返回登录界面</a> <%}%> </body> </html>