簡介:
驗證碼的作用:主要是為了有效防止機器惡意注冊,對某一個特定已注冊用戶用特定程序暴力破解方式進行不斷的登陸嘗試。驗證碼是現在很多網站注冊/登錄時必填的,雖然對用戶可能有點麻煩,但是對網站/社區來說這個功能還是很有必要,也很重要,不少網站為了防止用戶利用機器人自動注冊、登錄、灌水,都采用了驗證碼技術。所謂驗證碼,就是將一串隨機產生的數字或符號,生成一幅圖片, 圖片里加上一些干擾象素(防止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>