//验证码工具类

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

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;

import com.jfinal.core.Controller;
import com.jfinal.kit.StringKit;
import com.jfinal.render.Render;

public class MyCaptchaRender extends Render {

private static final long serialVersionUID = -7599510915228560611L;
     
        private static final String[] strArr = {"3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y"};
         
        private static String randomCodeKey = "JFINAL_JLHHWH_Key";
        private static boolean caseInsensitive = true;
         
        private int img_width = 85;
        private int img_height = 20;
        private int img_randNumber = 6;
         
        public MyCaptchaRender() {
        }
         
        public MyCaptchaRender(String randomKey) {
            if (StringKit.isBlank(randomKey))
                throw new IllegalArgumentException("randomKey can not be blank");
            randomCodeKey = randomKey;
        }
         
        public MyCaptchaRender(int width, int height, int count, boolean isCaseInsensitive) {      
            if(width <=0 || height <=0 || count <=0)
            {
                throw new IllegalArgumentException("Image width or height or count must be > 0");
            }
            this.img_width = width;
            this.img_height = height;
            this.img_randNumber = count;
            caseInsensitive = isCaseInsensitive;
        }
         
        public MyCaptchaRender(String randomKey,int width, int height, int count, boolean isCaseInsensitive) {
            if (StringKit.isBlank(randomKey))
                throw new IllegalArgumentException("randomKey can not be blank");
            randomCodeKey = randomKey;
             
            if(width <=0 || height <=0 || count <=0)
            {
                throw new IllegalArgumentException("Image width or height or count must be > 0");
            }
            this.img_width = width;
            this.img_height = height;
            this.img_randNumber = count;
            caseInsensitive = isCaseInsensitive;
        }
         
        public void render() {
            BufferedImage image = new BufferedImage(img_width, img_height, BufferedImage.TYPE_INT_RGB);
            String vCode = drawGraphic(image);
            vCode = encrypt(vCode);
            Cookie cookie = new Cookie(randomCodeKey, vCode);
            cookie.setMaxAge(-1);
            cookie.setPath("/");
            response.addCookie(cookie);
            response.setHeader("Pragma","no-cache");
            response.setHeader("Cache-Control","no-cache");
            response.setDateHeader("Expires", 0);
            response.setContentType("image/jpeg");
             
            ServletOutputStream sos = null;
            try {
                sos = response.getOutputStream();
                ImageIO.write(image, "jpeg",sos);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            finally {
                if (sos != null)
                    try {sos.close();} catch (IOException e) {e.printStackTrace();}
            }
        }
    
        private String drawGraphic(BufferedImage image){
            // 获取图形上下文
            Graphics g = image.createGraphics();
            // 生成随机类
            Random random = new Random();
            // 设定背景色
            g.setColor(getRandColor(200,250));
            g.fillRect(0, 0, img_width, img_height);
            // 设定字体
            g.setFont(new Font("Times New Roman", Font.PLAIN, 18));
    
            // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
            g.setColor(getRandColor(160, 200));
            for (int i = 0; i < 155; i++) {
                int x = random.nextInt(img_width);
                int y = random.nextInt(img_height);
                int xl = random.nextInt(12);
                int yl = random.nextInt(12);
                g.drawLine(x, y, x + xl, y + yl);
            }
    
            // 取随机产生的认证码(img_randNumber位数字)
            String sRand = "";
            for (int i = 0; i < img_randNumber; i++) {
                String rand = String.valueOf(strArr[random.nextInt(strArr.length)]);
                sRand += rand;
                // 将认证码显示到图象中
                g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
                // 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
                g.drawString(rand, 13 * i + 6, 16);
            }
    
            // 图象生效
            g.dispose();
             
            return sRand;
        }
         
        /*
         * 给定范围获得随机颜色
         */
        private Color getRandColor(int fc, int bc) {
            Random random = new Random();
            if (fc > 255)
                fc = 255;
            if (bc > 255)
                bc = 255;
            int r = fc + random.nextInt(bc - fc);
            int g = fc + random.nextInt(bc - fc);
            int b = fc + random.nextInt(bc - fc);
            return new Color(r, g, b);
        }
         
        private static final String encrypt(String srcStr) {
            try {
                String result = "";
                MessageDigest md = MessageDigest.getInstance("MD5");
                byte[] bytes = md.digest(srcStr.getBytes("utf-8"));
                for(byte b:bytes){
                    String hex = Integer.toHexString(b&0xFF).toUpperCase();
                    result += ((hex.length() ==1 ) ? "0" : "") + hex;
                }
                return result;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        public static boolean validate(Controller controller, String inputRandomCode) {
            if (StringKit.isBlank(inputRandomCode))
                return false;
            try {
                if(caseInsensitive)
                    inputRandomCode = inputRandomCode.toUpperCase();
                inputRandomCode = encrypt(inputRandomCode);
                return inputRandomCode.equals(controller.getCookie(randomCodeKey));
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
}

//Controller类(调用该方法来产生一个新的验证码)

public class CaptchaController extends Controller {
    /**
    * @Title: index
    * @Description: TODO(产生一个验证码)
    * void
    */
    public void index(){
        render(new MyCaptchaRender(60,22,4,true));
    }

//路由配置

public class FrontRoutes extends Routes
{
    public void config()
    {
            add("/captcha",CaptchaController.class);
    }

//页面代码

<body>

<img src="${path!}/captcha/index" id="checkCode" style="cursor: pointer;height: 70%;width: 80%;"  title="点击刷新验证码" />

</body>

<script type="text/javascript">

//点击更换验证码
$(function(){
    $("#checkCode").click(function(){
        $(this).attr("src","${path!}/captcha?d="+Math.random().toString());
    });
});
</script>

//效果图

Jfinal验证码功能的更多相关文章

  1. dd——留言板再加验证码功能

    1.找到后台-核心-频道模型-自定义表单 2.然后点击增加新的自定义表单 diyid 这个,不管他,默认就好 自定义表单名称 这个的话,比如你要加个留言板还是投诉建议?写上去呗 数据表  这个不要碰, ...

  2. .Net Core 之 图形验证码 本文介绍.Net Core下用第三方ZKWeb.System.Drawing实现验证码功能。

    本文介绍.Net Core下用第三方ZKWeb.System.Drawing实现验证码功能. 通过测试的系统: Windows 8.1 64bit Ubuntu Server 16.04 LTS 64 ...

  3. c#实现验证码功能

    一.验证码简介 验证码功能一般是用于防止批量注册的,不少网站为了防止用户利用机器人自动注册.登录.灌水,都采用了验证码技术.所谓验证码,就是将一串随机产生的数字或字母或符号或文字,生成一幅图片, 图片 ...

  4. javaweb实现验证码功能

    在javaweb的用户注册与登陆功能时,有时为了防止漏洞或者大量注册,可以使用验证码功能,下面是验证码的一个简单实现 验证码类 public class ValiImg extends HttpSer ...

  5. 使用JS来实现验证码功能

    最近想为自己的Django博客添加验证码功能,本来想使用第三方库来实现的,不过考虑到添加第三方库对性能的影响,以及第三方库是否安全可靠的问题,还是用自己的代码来实现吧.反正用JS来实现验证码功能又不是 ...

  6. 用PHP实现验证码功能

    目前,不少网站为了防止用户利用机器人自动注册.登录.灌水,都采用了 验证码技术.所谓验证码,就是将一串随机产生的数字或符号,生成一幅图片, 图片里加上一些干扰象素(防止OCR),由用户肉眼识别其中的验 ...

  7. ThinkPhp框架:验证码功能

    Think\Verify类可以支持验证码的生成和验证功能. 为了显示这个验证码功能,第一要有控制器,再就是有方法,然后是显示的页面. 一.最简单的方式生成验证码 (1)我们还是继续在那个控制器编写方法 ...

  8. 纯JS实现图片验证码功能并兼容IE6-8

    最近要搞一个图片验证码功能,但是又不想自己写后台代码.于是自己准备搞一个纯前端的验证码功能,于是网上搜索了一下,找到一个插件gVerify.js,简单好用,实现完美.不过后面接到说要兼容IE8,想想也 ...

  9. 用java来实现验证码功能(本帖为转载贴),作为个人学习收藏用

    一.关于为何使用验证的解释 在目前的网页的登录.注册中经常会见到各种验证码.其目的便是为了:防止暴力破解  .因为只要CPU性能较强,便可以在慢慢尝试密码的过程中来破解用户账号,因而导致的结果是用户信 ...

随机推荐

  1. DWZ分页、排序失效小结

    1. 在视图文件中与分页相关的代码段 <form id="pagerForm" method="post" action="w_list.htm ...

  2. POJ——3264线段树

    题目: 输入两个数(m,n),m表示牛的头数,n表示查询的个数.查询时输入两个数(x,y),表示查询范围的起始值和终止值,查询结果是,这个区间内牛重量的最大值减去牛重量的最小值,数量级为1000,00 ...

  3. selenium实战-自动退百度云共享群

    必备知识 在官网上下好selenium-3.0.1-py2.py3-none-any.whl,然后进入下载文件所在的位置 pip install selenium-3.0.1-py2.py3-none ...

  4. 枚举PEB获取进程模块列表

    枚举进程模块的方法有很多种,常见的有枚举PEB和内存搜索法,今天,先来看看实现起来最简单的枚举PEB实现获取进程模块列表. 首先,惯例是各种繁琐的结构体定义.需要包含 ntifs.h 和 WinDef ...

  5. 【java基础】内存分析

    在上次我们说的<重载与重写>呢,我们遗留了一个问题,就是运行结果的各异性,那今天,我们就来探究一下         内存里的天地.                  首先呢,我们把mian ...

  6. checkbox全选和子选

    用jq: $(function() { var $subBox = $("input[name='subBox']"); $("#checkAll").clic ...

  7. 用div,ul,input模拟select下拉框

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  8. dreamwaver cs6 主题配色方案

    这是css代码效果 这是js效果 这是html效果 使用方法:1.将下列代码自制到一个文本文档中,将文档命名为Colors.xml. 2.将Colors.xml放到C:\Users\tom\AppDa ...

  9. Ue4 BatteryCollector 教程笔记

    H UFUNCTION(BlueprintNativeEvent) void EventName(); virtual void EventName_Implementation(); EventNa ...

  10. 如何清除swap里的文件

    vi打开一个文件的时候突然断网,再次连接上去vi打开的时候提示在swap里面已经存在一个.要删除这个文件怎么办呢? 如下: 关了swapoff -a后 再ls -al查看 把文件所在目录里*.swp结 ...