jsp實現驗證碼


在web開發領域里面,驗證碼是一個比較常見的功能,而歸根到底,驗證碼其實就是一組隨機數,或者是一個隨機算術

一、基本知識

1、為什么需要驗證碼?

驗證碼,很多時候出現在注冊頁面或者登陸界面,在這些頁面中有可能會出現惡意注冊和暴力破解,這時候驗證碼可以有效防范這些攻擊。所以,總的來說,驗證碼很多時候是為了防止不法分子對網站進行惡意的注冊和攻擊,是一種有效的攔截手段。

2、驗證碼的工作原理

  首先,我們要明確一點就是,驗證碼實際是在服務器端產生的,因為如果在前端參數的話並不能有效攔截,因此很多時候,在攔截時我們都需要在服務器端進行相關操作,防止黑客繞過前端驗證直接非法訪問。

  驗證碼的工作原理其實方幾個步驟:首先,服務端隨機產生幾個隨機數或者隨機算式,然后通過session對象將數據傳輸到客戶端,客戶端輸入驗證碼,通過r表單將數據提交到服務器,服務器提取數據之后和產生的隨機數字或者算式的結果對比,以此進行驗證。

  當然,很多時候,簡單的驗證碼很容易被圖像識別軟件破解,所以現在很多時候更流行短信驗證等方式,但是,一下討論的均是簡單的數字圖片驗證。

二、驗證碼的實現過程

1、首先,驗證碼其實就是在服務端產生一張帶有驗證碼數字或者算式的圖片,所以,在這個過程要用到gui知識,具體請先看一下代碼

//1、驗證碼界面
	//驗證碼的寬和高
	int width = 70;
	int height = 30;
	/*
	*圖像緩沖對象(注意:在多次對某個對象操作時,為了提高效率,很多時候選擇用緩沖對象來進行操作,
	因為緩沖類的對象很多時候是可以即時改變對象的數據的)
	*/
	BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
	//創建圖像操作對象,用於操作驗證碼圖片對象
	Graphics2D g = bufferedImage.createGraphics();
	//創建字體對象方便操作圖像字體的屬性
	Font font = new Font("Times New Roman",Font.PLAIN,18);
	g.setFont(font);
	//設置相關顏色等等
	g.setColor(Color.BLACK);
	g.drawRect(0,0,width-1,height-1);
	g.setColor(Color.GRAY);

  以上創建了一個基本的驗證碼圖片,注意很多時候如果要反復對象對某個對象進行修改操作時(如某個字符串,需要反復進行拼接操作時,為提高性能,一般選擇用緩沖類的對象進行操作之后再轉換為相關對象)。以上是產生驗證碼的gui主要代碼,具體的步驟不啰嗦了,請參考代碼吧。

2、創建好相關的驗證碼圖片界面之后,下一步就是產生隨機數了,請先看以下代碼:

//2、產生隨機數
	//定義生成隨機數的對象
	Random random = new Random();
	//產生干擾線
	for(int i=0;i<40;i++){
		//設置40條干擾線
		int x1 = random.nextInt(width);
		int y1 = random.nextInt(height);
		int x2 = random.nextInt(10);
		int y2 = random.nextInt(10);
		//將隨機線條描繪到驗證碼對象中
		g.drawLine(x1,y1,x1+x2,y1+y2);
	}
	//產生隨機數
	//定義隨機數的個數
	int length = 4
	//定義 變量存儲隨機數字變量
	BufferedString str_random = new BufferedString();//定義成緩沖字符類型是為了提高效率
	for(int i=0;i<length;i++){
		int num_random = random.nextInt(10);
		String str_num = String.valueOf(num_random);
		g.drawString(str_num);
		str_random.append(str_num);
	}

  以上主要通過Random隨機數產生對象來產生隨機數字,其中注意要在反復第String類型操作的時候,將其定義成BufferedString進行操作比較高效。具體的操作並沒有涉及什么新技術,請查看代碼。

3、完成產生隨機數的步驟之后,剩下的就是將產生的隨機數發送出去了。請看代碼

//3、發送驗證碼圖片數據
	bufferedImg.flush();//刷新與圖像緩沖有關的數據
	g.dispose();//釋放與Graphice2D有關的對象的資源
	String randomCode = str_random.toString();
	session.setAttribute("randomCode",randomCode.toString());//通過session傳遞隨機碼給其他頁面用於驗證身份
	ServletOutputStream outputStream = response.getOutputStream();
	ImageIO.write(bufferedImg,"jpeg",outputStream);
	
	outputStream.close();
	
	out.clear();
	out=pageContext.pushBody();

  以上的發送驗證碼也是比較簡單,只是通過網絡流進行發送操作,其中,注意Graphics2D的資源釋放和IO流的關閉就好了。其中,將驗證碼通過session發送給其他頁面使用。

三、總結

以上實現了簡單的數字驗證碼功能,其中涉及到的技術主要是javaGUI、IO操作和servlet技術的session技術。類似的,實現算式的驗證碼也是類似的步驟,具體的就不多說,下面的代碼是實現了簡單的算式驗證碼的代碼參考:

int width = 70,height = 22;
	if(request.getParameter("width")!=null){
		try{
			width=Integer.parseInt(request.getParameter("width"));
		}catch(NumberFormatException e) {
			
		}
	}
	BufferedImage bufferedImg = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
	Graphics2D g = bufferedImg.createGraphics();
	
	g.setColor(Color.WHITE);
	g.fillRect(0,0,width,height);
	
	Font font = new Font("Times New Roman",Font.PLAIN,18);
	g.setFont(font);
	
	g.setColor(Color.BLACK);
	g.drawRect(0,0,width-1,height-1);
	g.setColor(Color.GRAY);
	
	Random random = new Random();//設置隨機種子
	
	for(int i=0;i<40;i++){
		//設置40條干擾線
		int x1 = random.nextInt(width);
		int y1 = random.nextInt(height);
		int x2 = random.nextInt(10);
		int y2 = random.nextInt(10);
		g.drawLine(x1,y1,x1+x2,y1+y2);
	}
	
	int length = 4;//設置默認生成四個長度的驗證碼
	if(request.getParameter("length")!=null){
		try{
			length = Integer.parseInt(request.getParameter("length"));
		}catch(NumberFormatException e){
			out.println("<script>alert('無法加載驗證碼,請重新操作!')</script");
			e.printStackTrace();
		}
	}
	//定義變量存儲運算結果
	int result = 0;
	//定義一個int用於存儲某個數字后面的運算符,1代表+,2代表-,初始化為0
	int int_sign = 0;
	for(int i = 0;i<length;i++){//獲取隨機數字字符串
		int num_random = random.nextInt(10);
		//根據符號標記標量int_sign進行相應的運算
		if(int_sign==2){
			result = result - num_random;
		}else{
			result = result + num_random;
		}
		String strRand = String.valueOf(num_random);
		g.setColor(Color.RED);
		g.drawString(strRand,13 * i + 6, 16);
		//隨機獲取運算符號
		if(i<length-1){
			int sign_random = random.nextInt(2);
			if(sign_random<1){
				g.setColor(Color.GREEN);
				g.drawString("+",13 * i + 12, 16);
				int_sign = 1;
			}else{
				g.setColor(Color.BLUE);
				g.drawString("-",13 * i + 12, 16);
				int_sign = 2;
			}
		}else{
			g.drawString("=?",13 * i + 12, 16);
		}
		
	}
	bufferedImg.flush();
	g.dispose();
	
	session.setAttribute("randomCode",result);
	
	response.setContentType("image/jpeg");
	response.setHeader("Pragam","no-cache");
	response.setHeader("Cache-Control","no-cache");
	response.setDateHeader("Expires",0);
	
	ServletOutputStream outputStream = response.getOutputStream();
	ImageIO.write(bufferedImg,"jpeg",outputStream);
	
	outputStream.close();
	
	out.clear();
	out=pageContext.pushBody();
	

  好了,驗證碼的總結就到此結束,有什么不足的地方請各位大神指正!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM