第三章:验证码问题

来源:互联网 发布:无线路由器网络模式 编辑:程序博客网 时间:2024/05/26 02:20

验证码相必大家都不陌生,那么验证码的作用到底是什么?多个验证码登录那么麻烦,为什么比较正规的网站都设定验证码呢?并且验证码的形式多种多样。首先我们先看下验证码究竟有哪些好处。

首先,验证码可以有效的防止一些黑客,以暴力的方式破解密码。现在许多网站或公司都设定有验证码,比如说腾讯,淘宝等等。为什么验证码加入后就能防止黑客暴力破解呢?验证码是服务器端自动生成的,存储在服务器内部,而我们前端得到的只是一张含有信息的图片,然而却无法获得信息,只有手动输入验证码,然后服务器端进行判断,所以就可以有效的防止某些非法用户以暴力的方式破解密码。

其次,验证码可以有效的防止暴力注册用户。产生了验证码,人注册起来明显感觉麻烦,用程序注册又无法自行判定验证码(仅个人认为),所以就有效的防止了暴力注册。

下面我们说下常见的验证码的格式:通常见到的验证码都是以字符A~Z+a~z+0~9组成的四位随机字符。还有的是随机生成的汉字(相对来说就比较麻烦),当然还有不是四位的随机字符,还有生成四则运算问结果,等等,总之验证码的种类多种多样,可以这么说,只要你本身足够牛,只有想不出的验证码种类,没有做不出的验证码。

下面以最简单的验证码为例,讲解一下验证码的工作原理。

首先我们打开Myeclipse,创建工程CodeCheckNew

创建ImagineServlet类(是Servlet类)

程序代码如下:
package cn.edu.hpu.acm.servlet;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class ImageServlet extends HttpServlet {


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


public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
//代表RGB颜色分量的8位图像,对应一个Windows风格BGR颜色模型)与蓝色,绿色,红色3个字节存储。
BufferedImage bi = new BufferedImage(70, 40, BufferedImage.TYPE_INT_BGR);
//创建一个画笔,并且继承BufferedImage类
Graphics g = bi.getGraphics();
//设置颜色new Color(int a,int b,int c);参数范围是0~255,自己随机设置
Color c = new Color(120,190,200);
//设置画笔颜色
g.setColor(c);
//设置验证码的随机生成范围char数组
char[] ch = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".toCharArray();
//生成伪随机数类r
Random r = new Random();
//设置文本类StringBuffer
StringBuffer sb = new StringBuffer();
//设置需要得到几个随机字符
for (int i = 0; i < 4; i++) {
//生成随机伪随机数r.nextInt(ch.length)并赋值给index
int index = r.nextInt(ch.length);
//设置画笔的书写方式,文字类型,以及文字大小
Font f = new Font("宋体",Font.BOLD ,20);
g.setFont(f);
//设置画笔颜色
g.setColor(new Color(r.nextInt(255),r.nextInt(255),r.nextInt(255)));
//设置画笔书写内容以及第一个字符的坐标
g.drawString(ch[index]+"",i*15+3,18);
//将字符逐个追加到sb文本中
sb.append(ch[index]);
}
//将文本强制转换为String类,并保存到piccode中
request.getSession().setAttribute("piccode", sb.toString());
//将图片发送过去,并设置类型
ImageIO.write(bi, "JPG", response.getOutputStream());
}
}

建立LoginServlet类,代码如下:此处省略登录帐号密码等,仅仅进行验证码的判定

代码如下:
package cn.edu.hpu.acm.servlet;


import java.io.IOException;
import java.io.PrintWriter;


import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class LoginServlet extends HttpServlet {


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


public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//设置编码方式,解决中文乱码
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
//得到服务器生成的验证码
String piccode = (String) request.getSession().getAttribute("piccode"); 
//得到用户输入的验证码
String checkcode = (String)request.getParameter("checkcode");

//System.out.println("---"+checkcode+"pic---"+piccode);
//验证码判定并返回结果
PrintWriter out = response.getWriter();
if(piccode.equalsIgnoreCase(checkcode)){
out.print("成功");
}else {
out.print("失败");
}
}
}
主页代码如下:
<%@ 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 'index.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">
<script type="text/javascript">
function reLodeCode(){
var time = new Data().getTime();
document.getElementById("imageCode").src="ImageServlet?id="+time;
}
</script>
  </head>
  
  <body>
  <form action="LoginServlet" method="post">
  验证码:<input name="checkCode" type="text">&nbsp;
  <img alt="验证码" src="ImageServlet" title="验证码" id="imageCode">&nbsp;
  <a herf="javaScript:reLoadCode()">看不清</a><br>
  <input value="提交" type="submit">
  </form>
  </body>
</html>

如此一个简单的验证码就完成了,这也是验证码的工作原理,大家想了解验证码更加高深的问题,可以在传智博客上去查找,那些有大神级写的功能非常强大的验证码。
本章到此结束。
1 1