Web功能设计:验证码

验证码

  • 简介
  • 实现

简介

验证码(CAPTCHA——Completely Automated Public Turing test to tell Computers and Humans Apart,全自动区分计算机和人类的图灵测试),是一种区分用户是计算机还是人的公共全自动程序。作用:防止恶意破解密码、刷票、论坛灌水或某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登录尝试。实际上用验证码是现在很多网站通行的方式,我们利用比较简易的方式实现了这个功能。这个问题可以由计算机生成并评判,但是必须只有人类才能解答。由于计算机无法解答CAPTCHA的问题,所以回答出问题的用户就可以被认为是人类。

在登录页面中,设置验证码个数为4个,内容包括有{0-9,A-Z,a-z},随机生成。当验证码输入有误时,也无法登录成功。验证码设计如下图:

Web功能设计:验证码_第1张图片

实现

首先,创建一个作验证码照片的工具类DrawIdentifyingCodeUtils.java:

package cn.edu.MVCcase.JDBC.utils;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

//作验证码照片的工具类
public class DrawIdentifyingCodeUtils {
    private int width; //宽
    private int height; //高
    private int num; //出现的个数
    private String code; //字典(验证码的内容从中选取)
    private static final Random random = new Random(); //随机选取
    private static DrawIdentifyingCodeUtils IdentifyingCode; //单列模式:指一个类只有一个实例,且该类能自行创建这个实例的一种模式

    private DrawIdentifyingCodeUtils() {
        //初始化
        code = "0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
        num = 4;
    }

    //单列模式获取对象的方法
    public static DrawIdentifyingCodeUtils getInstance() {
        if (IdentifyingCode == null) IdentifyingCode = new DrawIdentifyingCodeUtils();
        return IdentifyingCode;
    }

    public void set(int width,int height,int num,String code) {
        this.width = width;
        this.height = height;
        this.setNum(num);
        this.setCode(code);
    }

    public void set(int width,int height) {
        this.width = width;
        this.height = height;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    public int getNum() {
        return num;
    }

    public String getCode() {
        return code;
    }

    //生成验证码
    public String generateIdentifyingCode() {
        StringBuffer stringBuffer = new StringBuffer(); //可以存储和操作字符串,即包含多个字符的字符串数据
        //遍历四次,随机获取字符
        for(int i = 0; i < num; i++) {
            stringBuffer.append(code.charAt(random.nextInt(code.length())));
        }
        return stringBuffer.toString();
    }

    //作图
    public BufferedImage generateImage(String checkIdentifyingCode) {
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); //创建照片对象
        Graphics2D graphics2D = image.createGraphics(); //获取照片对象的画笔
        graphics2D.setColor(Color.WHITE);
        graphics2D.fillRect(0,0,width,height); //白色背景
        graphics2D.setColor(Color.GRAY); //换灰色
        graphics2D.drawRect(0,0,width-1,height-1);
        Font font = new Font("仿宋",Font.BOLD+Font.ITALIC,(int)(height*0.8)); //设置字体
        graphics2D.setFont(font);
        for(int i = 0; i < num; i++) {
            graphics2D.setColor(new Color(random.nextInt(155),random.nextInt(255),random.nextInt(255))); //随机颜色
            graphics2D.drawString(String.valueOf(checkIdentifyingCode.charAt(i)), i*(width/num)+4, (int)(height*0.8));
        }

        //加点
        for(int i = 0; i < (width+height); i++) {
            graphics2D.setColor(new Color(random.nextInt(155),random.nextInt(255),random.nextInt(255)));
            graphics2D.drawOval(random.nextInt(width), random.nextInt(height), 1, 1);
        }

        //加线
        for(int i = 0; i < 2; i++) {
            graphics2D.setColor(new Color(random.nextInt(155),random.nextInt(255),random.nextInt(255)));
            graphics2D.drawLine(0, random.nextInt(height), width, random.nextInt(height));
        }

        return image;
    }
}

调用作图类生成验证码的方法:

public void drawIdentifyingCode(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      //返回照片的内容类型
      resp.setContentType("image/jpg");
      int width = 150;
      int height = 45;
      DrawIdentifyingCodeUtils IdentifyingCode = DrawIdentifyingCodeUtils.getInstance();
      IdentifyingCode.set(width,height);
      String code = IdentifyingCode.generateIdentifyingCode();
      HttpSession session = req.getSession();
      session.setAttribute("checkIdentifyingCode",code);
      OutputStream outputStream = resp.getOutputStream();
      ImageIO.write(IdentifyingCode.generateImage(code),"jpg",outputStream);
  }

你可能感兴趣的:(前端,java,验证码)