Java生成验证码图片

来源:互联网 发布:php get 加密 编辑:程序博客网 时间:2024/06/06 06:49
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.FileOutputStream; import java.util.Random; import com.sun.image.codec.jpeg.JPEGCode

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.util.Random;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
  *  功能描述:  用来生成验证码图片,测试需要,常量,方法都设置成了static<br/>
*/
public class SecurityCodeCreater {
 
    //图片的宽度
    private final static int IMAGEWIDTH = 15;
    //图片的高度
    private final static int IMAGEHEIGHT = 22;
   
    //字体大小
    private final static int FONTSIZE = 18;
   
    //字符串长度
    private final static int CODE_LENGTH = 4;
   
    //随机字符范围
    private final static char[] CHAR_RANGE = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
                    'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
                    'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
                    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
                    'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
                    'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
                    '8', '9'
    }; 
   
    public static  void main(String[] args)throws Exception {
 
     //此main方法用来测试生成的验证码图像
    
     FileOutputStream fos = new FileOutputStream("c://test.jpg");
     JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(fos);
     encoder.encode(getImage(getRandString()));    
}
    
    private static Random random = new Random(); 
    
    /**
     * 生成随机字符串
     * @return 随机字符串 
     */
    private static String getRandString(){
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < CODE_LENGTH; i++)        
        
            sb.append(CHAR_RANGE[random.nextInt(CHAR_RANGE.length)]);
        return sb.toString();
    }
    
    /**
     * 生成随机颜色
     * @param ll 产生颜色值下限(lower limit)
     * @param ul 产生颜色值上限(upper limit)
     * @return 生成的随机颜色对象
     */
    private static Color getRandColor(int ll, int ul){
        if (ll > 255) ll = 255;
        if (ll < 1) ll = 1;
        if (ul > 255) ul = 255;
        if (ul < 1) ul = 1;
        if (ul == ll) ul = ll + 1;
        int r = random.nextInt(ul - ll) + ll;
        int g = random.nextInt(ul - ll) + ll;
        int b = random.nextInt(ul - ll) + ll;
        Color color = new Color(r,g,b);
        return color;
    }
    
    /**
     * 生成指定字符串的图像数据
     * @param verifyCode 即将被打印的随机字符串
     * @return 生成的图像数据
     * */
    private static BufferedImage getImage(String verifyCode){
        
     //生成画布
        BufferedImage image = new BufferedImage(IMAGEWIDTH * CODE_LENGTH, IMAGEHEIGHT, BufferedImage.TYPE_INT_RGB);
        
        //获取图形上下文 (生成画笔)
        Graphics graphics = image.getGraphics();
        
        //设置背景色()
        graphics.setColor(getRandColor(1,50));
       
        //填充矩形区域 ,作为背景
        graphics.fillRect(0, 0, IMAGEWIDTH * 4, IMAGEHEIGHT);
        
        //设置边框颜色
        graphics.setColor(new Color(0,255,0));
       
        //画出边框
        for (int i=0; i<2; i++)
            graphics.drawRect(i, i, IMAGEWIDTH * CODE_LENGTH - i * 2 - 1, IMAGEHEIGHT - i * 2 - 1);
        
        //设置随机干扰线条颜色
        graphics.setColor(getRandColor(50,100));
       
        //产生50条干扰线条
        for (int i=0; i<50; i++){
            int x1 = random.nextInt(IMAGEWIDTH * CODE_LENGTH - 4) + 2;
            int y1 = random.nextInt(IMAGEHEIGHT - 4) + 2;
            int x2 = random.nextInt(IMAGEWIDTH * CODE_LENGTH - 2 - x1) + x1;
            int y2 = y1;
            graphics.drawLine(x1, y1, x2, y2);
        }
        
        //设置字体
        graphics.setFont(new Font("Times New Roman", Font.PLAIN, FONTSIZE));
       
        //画字符串
        for (int i=0; i<CODE_LENGTH; i++){
        
         String temp = verifyCode.substring(i, i+1);
            graphics.setColor(getRandColor(100,255));
            graphics.drawString(temp, 13 * i + 6, 16);
        }
        
        //图像生效
        graphics.dispose();
        
        return image;

    }
}

验证码介绍:

有效防止这种问题对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上是用验证码是现在很多网站通行的方式(比如招商银行的网上个人银行,腾讯的QQ社区),我们利用比较简易的方式实现了这个功能。虽然登陆麻烦一点,但是对社区还来说这个功能还是很有必要,也很重要。但我们还是提醒大家主要保护自己的密码,尽量使用混杂了数字、字母、符号在内的6位以上密码,不要使用诸如1234之类的简单密码或者与用户名相同、类似的密码。 不要因为只是来iclub问问问题,就随意设置密码,保护你自己的密码也是保护你自己,免得你的账号给人盗用给自己带来不必要的麻烦。 ~
(1).验证码一般是防止批量注册的,人眼看起来都费劲,何况是机器。二像百度贴吧未登录发贴要输入验证码大概是防止大规模匿名回帖的发生目前,不少网站为了防止用户利用机器人自动注册、登录、灌水,都采用了验证码技术。所谓验证码,就是将一串随机产生的数字或符号,生成一幅图片, 图片里加上一些干扰象素(防止OCR),由用户肉眼识别其中的验证码信息,输入表单提交网站验证,验证成功后才能使用某项功能。
(2).一般注册用户ID的地方以及各大论坛都要要输入验证码
(3).常见的验证码
1,四位数字,随机的一数字字符串,最原始的验证码,验证作用几乎为零。2,CSDN网站用户登录用的是GIF格式,目前常用的随机数字图片验证码。图片上的字符比较中规中矩,验证作用比上一个好。没有基本图形图像学知识的人,不可破!可惜读取它的程序,在CSDN使用它的第一天,好像就在论坛里发布了,真是可怜!
3,QQ网站用户登录用的是PNG格式,图片用的随机数字+随机大写英文字母,整个构图有点张扬,每刷新一次,每个字符还会变位置呢!有时候出来的图片,人眼都识别不了,厉害啊…4,MS的hotmail申请时候的是BMP格式, 随机数字+随机大写英文字母+随机干扰像素+随机位置。
5,Google的Gmail注册时候的是JPG格式,随机英文字母+随机颜色+随机位置+随机长度。6,其他各大论坛的是XBM格式,内容随机。
(4)意义:不少网站为了防止用户利用机器人自动注册、登录、灌水,都采用了验证码技术。所谓验证码,就是将一串随机产生的数字或符号,生成一幅图片,图片里加上一些干扰象素(防止OCR),由用户肉眼识别其中的验证码信息,输入表单提交网站验证,验证成功后才能使用某项功能。