文档章节

java 加减运算 验证码 防用户恶意登录

为为02
 为为02
发布于 2016/08/22 18:43
字数 869
阅读 176
收藏 1

本验证码用于java web,这是基于一个servlet构建的验证码小程序。具体实现效果如图所示

为了能让初学者明白,首先放上类图:

然后本类构造图

源码上有必要注释,具体怎么用就不详细说明了

最后奉献出源码:

package cn.hn3l.controler.graphics;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

/**
 * Created by Wang Weiwei on 2016/8/22.
 * @version 1.0 BATA
 *
 */
@WebServlet(name = "captcha",urlPatterns = {"/captcha"})
public class Captcha extends HttpServlet {

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

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        OutputStream outputStream = response.getOutputStream();
        BufferedImage bufferedImage = new BufferedImage(200, 50 ,BufferedImage.TYPE_INT_RGB);
        //设置服务器回应头
        response.setHeader("Pragma","No-cache");
        response.setHeader("Cache-Control","no-cache");
        response.setDateHeader("Expires", 0);
        //表明生成的响应是图片
        response.setContentType("image/jpeg");
        //绘制验证码
        int sResult = drawCaptcha(bufferedImage);
        System.out.println(sResult);
        request.getSession().setAttribute("sResult", sResult);
        //通过ImageIO将image写入到服务器响应输出流中
        ImageIO.write(bufferedImage, "JPEG",outputStream);
    }

    private int drawCaptcha(BufferedImage bufferedImage) {
        Graphics2D graphics2D = bufferedImage.createGraphics();
        //画背景
        graphics2D.setColor(getRandomColor(200, 250));
        graphics2D.fillRect(0, 0,200,50);
        int width = 200;
        int height = 50;
        //画干扰线
        grawRandomLine(width, height, graphics2D);
        //画字符以及符号
        return drawNum(getNums(),graphics2D);
    }

    /**画出验证码干扰线*/
    private void grawRandomLine(int width, int height, Graphics2D graphics2D) {
        //画200条短线
        for (int i = 0; i < 200; i++) {
            graphics2D.setStroke(new BasicStroke(random.nextInt(3)));
            graphics2D.setColor(getRandomColor(0, 255));
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int x2 = random.nextInt(30);
            int y2 = random.nextInt(20);
            graphics2D.drawLine(x, y, x + x2, y + y2);
        }
        //画5条长线
        for (int i = 0; i < 5; i++) {
            graphics2D.setStroke(new BasicStroke(random.nextInt(5)));
            graphics2D.setColor(getRandomColor(80, 120));
            int x = random.nextInt(width - 50);
            int y = random.nextInt(height);
            int x2 = 50;
            int y2 = random.nextInt(20);
            graphics2D.drawLine(x, y, x + x2, y + y2);
        }
        for (int j = 0; j < 200; j++) {
            graphics2D.setStroke(new BasicStroke(random.nextInt(4)));
            graphics2D.setColor(getRandomColor(180, 230));
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int x2 = random.nextInt(width);
            int y2 = random.nextInt(height);
            graphics2D.drawLine(x, y, x2, y2);
        }

    }

    /**画数字*/
    private int drawNum(int[] nums, Graphics2D graphics2D) {
        //获取操作符
        char[] sysbols = {'+', '-'};
        int[] symbol = getSymbol(nums.length);
        int beginPointX = 10;
        int beginPointY = 20;
        for (int i = 0; i < nums.length; i++) {

            String numStr = String.valueOf(nums[i]);
            for (int j = 0; j < numStr.length(); j++) {
                setGraphicProperty(graphics2D);
                graphics2D.drawString(String.valueOf(numStr.charAt(j)),
                        beginPointX + random.nextInt(10), beginPointY + random.nextInt(10));
                beginPointX += 20;
                setGraphicProperty(graphics2D);
            }
            if(i < symbol.length){
                graphics2D.drawString(String.valueOf(sysbols[symbol[i] - 1]),
                        beginPointX + random.nextInt(10), beginPointY + random.nextInt(10));
                beginPointX += 20;
            }else {
                graphics2D.drawString(String.valueOf("="),
                        beginPointX + random.nextInt(10), beginPointY + random.nextInt(10));
                beginPointX += 20;
            }

        }
        graphics2D.drawString(String.valueOf("?"),
                beginPointX + random.nextInt(10), beginPointY + random.nextInt(10));
        return getValue(nums, symbol);
    }

    /**获取验证码结果*/
    private int getValue(int[] nums, int[] symbol) {
        int temp = 0;
        for (int i = 0; i < nums.length; i++) {
            if (i == 0){
                temp = nums[i];
            }else {
                switch (symbol[i - 1]){
                    case 1:
                        temp += nums[i];
                        break;
                    case 2:
                        temp -= nums[i];
                        break;
                }
            }
        }
        return temp;
    }

    private void setGraphicProperty(Graphics2D graphics2D) {
        graphics2D.setFont(setFont(random.nextInt(4)));
        graphics2D.setColor(getRandomColor(50,100));
        graphics2D.setStroke(new BasicStroke(random.nextInt(4)));
    }

    /**获取操作符
     * 1:'+'
     * 2:'-'*/
    private int[] getSymbol(int length) {
        int[] symbol = new int[length - 1];
        for (int i = 0; i < symbol.length; i++) {
            symbol[i] = random.nextInt(2) + 1;
        }
        return symbol;
    }

    /**获取随机颜色
     * @param fc 前景色
     * @param bc 背景色
     * @return  具体返回颜色为rgb颜色,其值在fc和bg之间随机*/
    private Color getRandomColor(int fc, int bc) {
        int difference = bc - fc;
        int red = random.nextInt(difference) + fc;
        int green = random.nextInt(difference) + fc;
        int blue = random.nextInt(difference) + fc;
        return new Color(red, green,blue);
    }

    //随机数控制
    private Random random = new Random();

    private int[] getNums() {
        //共有size个数()
        int size = random.nextInt(2) + 2;
        int[] nums = new int[size];
        for (int i = 0; i < size; i++) {
            nums[i] = random.nextInt(13);
        }
        return nums;
    }

    /**随机获取四种默认字体中的某种字体*/
    public Font setFont(int font) {
        Font[] fonts = new Font[4];
        fonts[0] = new Font("Times New Roman", Font.PLAIN, 30);
        fonts[1] = new Font("Times New Roman", Font.BOLD, 28);
        fonts[2] = new Font("Times New Roman", Font.ITALIC, 30);
        fonts[3] = new Font("Times New Roman", Font.PLAIN, 28);
        return fonts[font];
    }
}

 

 

© 著作权归作者所有

为为02
粉丝 51
博文 44
码字总数 99356
作品 0
海淀
程序员
私信 提问
java识别加减运算验证码

用java写一个程序,用来识别加减运算验证码,求大佬分享

我还是妹子啊
2018/11/05
329
2
Spring Security之用户名+密码登录

自定义用户认证逻辑 处理用户信息获取逻辑 实现UserDetailsService接口 处理用户校验逻辑 UserDetails接口的一些方法,封装了登录时的一些信息 返回数据写成 处理密码加密解密 PasswordEnco...

yysue
2018/10/11
691
0
Java 工具 Hutool-4.0.0 正式发布:从懵懂到成熟

Hutool是一个Java工具包,也只是一个工具包,它帮助我们简化每一行代码,减少每一个方法,让Java语言也可以“甜甜的”。Hutool最初是我项目中“util”包的一个整理,后来慢慢积累并加入更多非...

路小磊
2018/01/13
8.7K
64
从.Net到Java学习第十一篇——SpringBoot登录实现

通过前面10篇文章的学习,相信我们对SpringBoot已经有了一些了解,那么如何来验证我们的学习成果呢?当然是通过做项目来证明吧!所以从这一篇开始我将会对之前自己做的.net项目用java来重写。...

邹琼俊
2018/07/13
0
0
【Help!】朋友的亲戚家的熊孩子毕业JAVA答辩题难倒俺了!

朋友家的亲戚家的孩子毕业JAVA题答辩。这熊孩子不好好学习天天就知道玩儿帅哥,这不连JAVA啥模样都不知道,于是求助俺,当时俺那个无奈啊,俺一个搞前端的屌丝哪里懂JAVA这么高级的产物。没办...

guke01
2014/06/30
826
16

没有更多内容

加载失败,请刷新页面

加载更多

深入理解表单脚本系列第二篇——表单字段

本文转载于:专业的前端网站➜深入理解表单脚本系列第二篇——表单字段 前面的话   表单字段又叫表单元素,表示表单所包含控件,如<input>、<select>等。本文将详细介绍表单字段的内容 访问...

前端老手
23分钟前
5
0
前端技术之:常用webpack插件

1、html-webpack-plugin Simplifies creation of HTML files to serve your webpack bundles. 主页地址: https://github.com/jantimon/html-webpack-plugin 安装方法: npm i --save-dev h......

popgis
28分钟前
6
0
IT兄弟连 HTML5教程 HTML5表单 多样的输入类型1

HTML5拥有多个新的表单输入类型,这些新特性提供了更好的输入控制和验证。并不是所有的主浏览器都支持新的input类型,不过我们可以在所有的主浏览器中使用它们,即使不被支持,仍然可以显示为...

老码农的一亩三分地
29分钟前
6
0
规则引擎

解决问题 版本迭代速度更不上业务变化,但是若多个业务同时变化,除了为每个业务设计专属配置项也不利于操作。就想服务接口单纯化,将复杂多变的业务逻辑交给规则引擎,让用户在web端或cs端自...

无极之岚
今天
7
0
OSChina 周三乱弹 —— 欢迎你来做产品经理

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 :10多次劲歌金曲获奖,更多叱咤歌坛排名,黎明才应该是四大天王之首,只可惜拍的电影太少。单曲循环一个多月的歌,力荐 《无名份的...

小小编辑
今天
836
11

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部