java开发之验证码

来源:互联网 发布:python tuple 和 array 编辑:程序博客网 时间:2024/06/17 03:41

什么是验证码

所谓验证码(CAPTCHA),就是将一串随机产生的数字或符号,生成一幅图片,由用户肉眼识别其中的验证码信息,输入表单提交网站验证,验证成功后才能使用某项功能。

验证码的作用及种类

验证码的主要作用一般是防止批量注册的和恶意程序暴力破解登录密码。目前,不少网站为了防止用户利用机器人自动注册、登录、灌水,都采用了验证码技术。验证码实际上是动态生成的一幅图片,图片里加上一些干扰象素(防止OCR),以增加恶意程序自动识别的难度。

 

常见的验证码有以下几种:

数字验证码。随机的一组数字,最原始的验证码,验证作用几乎为零。

数字图片验证码。图片上的字符比较中规中矩,验证作用比上一个好。

汉字图片验证码。更难识别,输入也更麻烦。

随机数字+随机英文字母+随机干扰像素+随机位置图片。

MIME类型

MIME的英文全称是“Multipurpose Internet Email Extension” 是一种多用途网际邮件扩充协议

MIME设计的最初目的是为了在发送电子邮件时附加多媒体数据,让邮件客户程序能根据其类型进行处理。然而当它被HTTP协议支持之后,它的意义就更为显著了。它使得HTTP传输的不仅是普通的文本,而变得丰富多彩。

文件类型 

 

参考代码:

public class ValidateCodeServlet extends HttpServlet {

       //将来存放验证码值的session的key值

       public static final String VALIDATE_CODE_KEY = "ValidateCode";

 

       //请求servlet的时的被调方法

       public void doGet(HttpServletRequest request, HttpServletResponse response)

                     throws ServletException, IOException {

 

//设置文档的内容类型为jpeg类型,

//从而在浏览的时候告知浏览器这是一个图片类型

response.setContentType("image/jpeg");

              //生成验证码,保存在session中

              HttpSession session = request.getSession();

             

//调用下面的generateString方法,

//生成一个4位长的每位为0-9的随机字符串

 

              String code = generateString();

              session.setAttribute(VALIDATE_CODE_KEY, code);

 

              //生出内存图片

              BufferedImage image = generateImage(code);

 

              //输出图片

              outputImage(image, response.getOutputStream());

       }

 

 

       //往页面输出的方法

       private void outputImage(BufferedImage image, ServletOutputStream out)

                     throws IOException {

              ImageWriter writer = null;

              //下面进行对图片格式的一些修改

              ImageTypeSpecifier type =

ImageTypeSpecifier.createFromRenderedImage(image);

              Iterator iter = ImageIO.getImageWriters(type, "jpg");

              if (iter.hasNext()) {

                     writer = (ImageWriter) iter.next();

              }

             

              IIOImage iioImage = new IIOImage(image, null, null);

              ImageWriteParam param = writer.getDefaultWriteParam();

 

              param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);

              //控制图片质量,1.0最高

              param.setCompressionQuality(1.0F);

              //创建输出流

              ImageOutputStream outputStream = ImageIO.createImageOutputStream(out);

              //将构建好的图片输出流写入到页面中

              writer.setOutput(outputStream);

              writer.write(null, iioImage, param);

       }

 

      

       //用来生成随机字符串的方法

private String generateString() {

              int a = (int) (Math.random() * 10);

              int b = (int) (Math.random() * 10);

              int c = (int) (Math.random() * 10);

              int d = (int) (Math.random() * 10);

              return "" + a + b + c + d;

       }

      

       //生成图片的方法

       private BufferedImage generateImage(String code) {

              //设置图片信息,宽,高,具有 8 位 RGB 颜色分量的图像

              BufferedImage image = new BufferedImage(100, 30,

                            BufferedImage.TYPE_INT_RGB);

              //得到画笔

              Graphics g = image.getGraphics();

              //产生背景图片

              g.setColor(Color.white);

              //画矩形框

              g.fillRect(1, 1, 98, 28);

              //添加干扰线

              for (int i = 0; i < 20; i++) {

                     g.setColor(generateColor());

                     int x1 = (int) (Math.random() * 100);

                     int y1 = (int) (Math.random() * 30);

                     int x2 = (int) (Math.random() * 100);

                     int y2 = (int) (Math.random() * 30);

                     g.drawLine(x1, y1, x2, y2);

              }

              //画数字

              //得到不同效果的随机字符串

              //使其颜色或者其他信息有所不同

              g.setFont(new Font("IMPACT", Font.PLAIN,

                            20 + (int) (Math.random() * 10)));

              g.setColor(generateColor());

              g.drawString(code.charAt(0) + "", 5, 28);

              g.setFont(new Font("IMPACT", Font.PLAIN,

                            20 + (int) (Math.random() * 10)));

              g.setColor(generateColor());

              g.drawString(code.charAt(1) + "", 30, 28);

 

              g.setFont(new Font("IMPACT", Font.PLAIN,

                            20 + (int) (Math.random() * 10)));

              g.setColor(generateColor());

              g.drawString(code.charAt(2) + "", 55, 28);

 

              g.setFont(new Font("IMPACT", Font.PLAIN,

                            20 + (int) (Math.random() * 10)));

              g.setColor(generateColor());

              g.drawString(code.charAt(3) + "", 80, 28);

 

              return image;//返回制作好的图像

       }

    

       //生成随机的颜色

       private Color generateColor() {

              int r = (int) (Math.random() * 180);

              int g = (int) (Math.random() * 180);

              int b = (int) (Math.random() * 180);

              return new Color(r, g, b);

       }

}


在xml文件中的配置:

<servlet>

    <description>This is the description of my J2EE component</description>

    <display-name>This is the display name of my J2EE component</display-name>

    <servlet-name>ValidateCodeServlet</servlet-name>

    <servlet-class>org.xawl.jsj.ValidateCodeServlet</servlet-class>

  </servlet>

 

  <servlet-mapping>

    <servlet-name>ValidateCodeServlet</servlet-name>

    <url-pattern>/servlet/validatecode</url-pattern>

</servlet-mapping>

在jsp页面中的操作:

<%@ page language="java"  pageEncoding="gb2312" %>

<html>

  <head>

    <script type="text/javascript">

       function change(){

           var imgcode = document.getElementByIdx("codeimg");

           imgcode.src="servlet/validatecode?"+new Date();

       }

    </script>

  </head>

  <body>

  <form action="check.jsp" method="post" >

    验证码:<img alt="" src="servlet/validatecode">    <a href="#" onclick="change();">点击更换</a> <br>

    <input type="text" name="code" >    <br>

    <input type="submit"  value="验证" >    <br>

   </form>

  </body>

</html>


原创粉丝点击