驗證碼

一、驗證碼簡介

  一次性驗證碼的主要目的就是爲了限制人們利用工具軟件來暴力猜測密碼。

  服務器程序接收到表單數據後,首先判斷用戶是否填寫了正確的驗證碼,只有該驗證碼與服務器保存的驗證碼匹配的時候,服務器程序才能正常的處理表單。

  密碼猜測工具要逐一嘗試每個密碼的前提條件是先輸入正確的驗證碼,而驗證碼是一次性有效的,這樣基本上就阻斷了密碼猜測工具的自動處理過程。


二、驗證碼的實現

package cn.session;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.p_w_picpath.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.p_w_picpathio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*驗證碼*/
@SuppressWarnings("serial")
public class CheckCode extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		int width = 120;
		int height = 30;
		//在內存中生成圖片
		BufferedImage p_w_picpath = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		
		//先獲取畫筆
		Graphics2D g = (Graphics2D) p_w_picpath.getGraphics();
		
		//設置畫筆的顏色爲灰色
		g.setColor(Color.gray);
		//畫填充的矩形
		g.fillRect(0, 0, width, height);
		
		//設置畫筆的顏色爲藍色,畫邊框
		g.setColor(Color.BLUE);
		g.drawRect(0, 0, width-1, height-1);
		
		
		//下面是畫隨機數
		//準備好數據,隨意獲取4個字符
		String words = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
		
		//設置畫筆的顏色爲黃色,設置字體
		g.setColor(Color.YELLOW);
		g.setFont(new Font("微軟雅黑,隸書", Font.BOLD, 20));
		
		StringBuffer sb = new StringBuffer();
		
		Random random = new Random();
		int x = 20;//設置驗證碼中字的左邊距
		int y = 20;//設置驗證碼中字的上邊距
		for (int i = 0; i < 4; i++) {
			//void rotate(double theta,double x,double y)
			//theta 弧度
			//hudu = jiaodu * Math.PI /180;
			//jiaodu在正負30之間
			int jiaodu = random.nextInt(60) - 30;
			double hudu = jiaodu * Math.PI / 180;
			g.rotate(hudu, x, y);
			
			//獲取下標
			int index = random.nextInt(words.length());
			//返回指定下標位置的字符串,隨機獲取字符
			char ch = words.charAt(index);
			
			//把字符拼湊成起來,以便用於存放入session中
			sb.append(ch);
			
			//畫驗證碼中的內容即4個隨機數
			g.drawString(""+ch, x, y);
			
			//將弧度歸位
			g.rotate(-hudu, x, y);
			x+= 20;//設置驗證碼中的字符之間的距離是20
		}
		//將驗證碼中的字符放入到session中
		request.getSession().setAttribute("code", sb.toString());
		
		//設置畫筆顏色
		g.setColor(Color.GREEN);
		int x1,x2,y1,y2;
		//畫干擾線
		//兩點確定一條直線
		//而且干擾線的座標(x1,y1)(x2,y2)不能超過驗證碼的寬和高
		for (int i = 0; i < 4; i++) {
			x1 = random.nextInt(width);
			y1 = random.nextInt(height);
			x2 = random.nextInt(width);
			y2 = random.nextInt(height);
			g.drawLine(x1, y1, x2, y2);
		}
		//將驗證碼輸出到客戶端
		ImageIO.write(p_w_picpath, "jpg", response.getOutputStream());
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		this.doGet(request, response);
	}

}


三、驗證碼封裝到jsp頁面

<%@page import="javax.p_w_picpathio.ImageIO"%>
<%@page import="java.awt.Font"%>
<%@page import="java.awt.Color"%>
<%@page import="java.awt.Graphics2D"%>
<%@page import="java.awt.p_w_picpath.BufferedImage"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'identifyingCde;.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
<%
	int width = 120;
		int height = 30;
		//在內存中生成圖片
		BufferedImage p_w_picpath = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		
		//先獲取畫筆
		Graphics2D g = (Graphics2D) p_w_picpath.getGraphics();
		
		//設置畫筆的顏色爲灰色
		g.setColor(Color.gray);
		//畫填充的矩形
		g.fillRect(0, 0, width, height);
		
		//設置畫筆的顏色爲藍色,畫邊框
		g.setColor(Color.BLUE);
		g.drawRect(0, 0, width-1, height-1);
		
		
		//下面是畫隨機數
		//準備好數據,隨意獲取4個字符
		String words = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
		
		//設置畫筆的顏色爲黃色,設置字體
		g.setColor(Color.YELLOW);
		g.setFont(new Font("微軟雅黑,隸書", Font.BOLD, 20));
		
		StringBuffer sb = new StringBuffer();
		
		Random random = new Random();
		int x = 20;//設置驗證碼中字的左邊距
		int y = 20;//設置驗證碼中字的上邊距
		for (int i = 0; i < 4; i++) {
			//void rotate(double theta,double x,double y)
			//theta 弧度
			//hudu = jiaodu * Math.PI /180;
			//jiaodu在正負30之間
			int jiaodu = random.nextInt(60) - 30;
			double hudu = jiaodu * Math.PI / 180;
			g.rotate(hudu, x, y);
			
			//獲取下標
			int index = random.nextInt(words.length());
			//返回指定下標位置的字符串,隨機獲取字符
			char ch = words.charAt(index);
			
			//把字符拼湊成起來,以便用於存放入session中
			sb.append(ch);
			
			//畫驗證碼中的內容即4個隨機數
			g.drawString(""+ch, x, y);
			
			//將弧度歸位
			g.rotate(-hudu, x, y);
			x+= 20;//設置驗證碼中的字符之間的距離是20
		}
		//將驗證碼中的字符放入到session中
		request.getSession().setAttribute("code", sb.toString());
		
		//設置畫筆顏色
		g.setColor(Color.GREEN);
		int x1,x2,y1,y2;
		//畫干擾線
		//兩點確定一條直線
		//而且干擾線的座標(x1,y1)(x2,y2)不能超過驗證碼的寬和高
		for (int i = 0; i < 4; i++) {
			x1 = random.nextInt(width);
			y1 = random.nextInt(height);
			x2 = random.nextInt(width);
			y2 = random.nextInt(height);
			g.drawLine(x1, y1, x2, y2);
		}
		//將驗證碼輸出到客戶端
		ImageIO.write(p_w_picpath, "jpg",response.getOutputStream());	
		out.clear();  
		out = pageContext.pushBody();  
 %>
  </body>
</html>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章