给大家分享一下自己写的验证码api,有汉字、字母数字两类

鉴于验证码使用极其频繁,今天就写了个自己的验证码api,大家不要扔砖块。微笑

先给大家看看效果:

//这是一个测试类,分别产生50个数字字母验证码和汉字验证码

//验证码对象有很多属性,比如字体,干扰线数目,干扰线颜色因子,中穿线最大数目,中穿线权重,字符串长度,验证码图片的大小,写入到指定流....等等.在此不便赘述

package authcode;


import java.io.File;
import java.io.IOException;


public class Test3 {
public static void main(String[] args) {
CharNumAuthCode charNumAuthCode=new CharNumAuthCode();
ChineseAuthCode chineseAuthCode=new ChineseAuthCode();
for(int i=1;i<=50;i++){
try {
charNumAuthCode.write("PNG",new File("C:\\a\\"+i+".png"));
chineseAuthCode.write("PNG",new File("C:\\b\\"+i+".png"));
charNumAuthCode.next();
chineseAuthCode.next();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}


下面是产生的验证码截图:








下面给出源码:

package authcode;


import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;


import javax.imageio.stream.ImageOutputStream;


/**
 * 验证码接口
 * @author 傲世孤尘
 *
 */
public interface IAuthCode {
/**
* 默认的字符串长度
*/
public static final int defaultStringLength=4;
/**
* 默认的验证码宽度
*/
public static final int defaultWidth=120;
/**
* 默认的验证码高度
*/
public static final int defaultHeight=40;
/**
* 默认的干扰线权重,权重越大,则干扰线越长
*/
public static final int defaultDisturbLineWeight=3;
/**
* 第一个影响干扰线颜色的因子,范围在0到255之间
*/
public static final int defaultDisturbLineFc=50;
/**
* 第二个影响干扰线颜色的因子,范围在0到255之间
*/
public static final int defaultDisturbLineBc=230;
/**
* 默认的干扰线数目
*/
public static final int defaultDisturbLineCount=200;
/**
 * 默认的字符最大倾斜度
 */
public static final int defaultMaxGradient=35;
/**
* 默认的字符上边距
*/
public static final int defaultTopPadding=30;
/**
* 默认的字符左边距
*/
public static final int defaultLeftPadding=20;
/**
* 默认的字符间距
*/
public static final int defaultSpaceBetween=25;
/**
* 默认的字体
*/
public static final Font defaultFont=new Font("宋体",Font.BOLD,28);
/**
* 第一个影响字体颜色的因子
*/
public static final int defaultFontColorMinValue=100;
/**
* 第二个影响字体颜色的因子
*/
public static final int defaultFontColorMaxValue=120;
/**
* 默认的中穿线最大条数
*/
public static final int defaultThreadingMaxCount=3;
/**
* 默认的中穿线权重
*/
public static final int defaultThreadingWeight=80;
/**
* 第一个影响中穿线颜色的因子
*/
public static final int defaultThreadingFc=20;
/**
* 第二个影响中穿线颜色的因子
*/
public static final int defaultThreadingBc=230;
/**
* 验证码的初始化方法,并产生随机禅定第一张验证码
* @param width 验证码宽度
* @param height 验证码高度
* @param stringLength 验证码字符串长度
*/
public void init(int width,int height,int stringLength);
/**
* 获取一张验证码图片
* @return 验证码图片
*/
public BufferedImage getImage();
/**
* 获取当前验证码图片,并且自动产生下一张验证码,更新成员中的验证码图片
* @return 当前验证码图片
*/
public BufferedImage next();
/**
* 获取验证码的字符串内容
* @return 当前验证码内容
*/
public String getContent();
/**
* 比较指定字符串是否与验证码内容一致,忽略大小写差异
* @param content 要判断的字符串
* @return 是否一致
*/
public boolean contrast(String content);
/**
* 或去一个随机字符串,字符个数由参数指定,若没有指定,则使用默认字符串长度,所有字符为数字和字母的组合
* @return 产生的字符串
*/
public String getRandomString();
/**
* 根据字符串内容,画出验证码图片,并更新成员中的验证码图片
* @param content 要画的字符串内容
* @return 当前画出的验证码图片
*/
public BufferedImage draw(String content);
/**
* 将当前的验证码图片以指定格式写入到指定文件
* @param formatName 图片格式
* @param output 要写入的文件
* @return 操作成功与否
*/
public boolean write(String formatName,File output)throws IOException;
/**
* 使用支持给定格式的任意 ImageWriter 将验证码图片写入 ImageOutputStream。
* 从当前流指针开始将图像写入 ImageOutputStream,并重写该点之后的现有流数据,如果有的话。
* @param formatName 图片格式
* @param output 指定的输出流
* @return 操作成功与否
*/
public boolean write(String formatName,ImageOutputStream output)throws IOException;
/**
* 使用支持给定格式的任意 ImageWriter 将验证码图片写入 OutputStream。 
* @param formatName 图片格式
* @param output 指定的输出流
* @return 操作成功与否
*/
public boolean write(String formatName,OutputStream output) throws IOException;
}


//然后下面是一个抽象类,实现了大部分方法

package authcode;


import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;


import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;


/**
 * 字符数字验证码
 * @author 傲世孤尘
 *
 */
public abstract class AbstractAuthCode implements IAuthCode{
/**
* 验证码内容
*/
String content;
/**
* 验证码图片
*/
BufferedImage image;
/**
* 验证码内容长度
*/
int stringLength;
/**
* 验证码图片宽度
*/
int width;
/**
* 验证码图片高度
*/
int height;
/**
* 干扰线权重,权重越大,则干扰线越长
*/
int disturbLineWeight;
/**
* 第一个影响干扰线颜色的因子,范围在0到255之间
*/
int disturbLineFc;
/**
* 第二个影响干扰线颜色的因子,范围在0到255之间
*/
int disturbLineBc;
/**
* 干扰线数目
*/
int disturbLineCount;
/**
 * 字符最大倾斜度
 */
int maxGradient;
/**
* 字符上边距
*/
int topPadding;
/**
* 字符左边距
*/
int leftPadding;
/**
* 字符间距
*/
int spaceBetween;
/**
* 验证码内容使用的字体
*/
Font font;
/**
* 第一个影响字体颜色的因子
*/
int fontColorMinValue;
/**
* 第二个影响字体颜色的因子
*/
int fontColorMaxValue;
/**
* 中穿线最大条数
*/
int threadingMaxCount;
/**
* 中穿线权重
*/
int threadingWeight;
/**
* 第一个影响中穿线颜色的因子
*/
int threadingFc;
/**
* 第二个影响中穿线颜色的因子
*/
int threadingBc;

@Override
public void init(int width, int height,int stringLength) {
// TODO Auto-generated method stub
this.width=width;
this.height=height;
this.stringLength=stringLength;
this.disturbLineWeight=defaultDisturbLineWeight;
this.disturbLineFc=defaultDisturbLineFc;
this.disturbLineBc=defaultDisturbLineBc;
this.disturbLineCount=defaultDisturbLineCount;
this.maxGradient=defaultMaxGradient;
this.topPadding=defaultTopPadding;
this.leftPadding=defaultLeftPadding;
this.spaceBetween=defaultSpaceBetween;
this.font=defaultFont;
this.fontColorMinValue=defaultFontColorMinValue;
this.fontColorMaxValue=defaultFontColorMaxValue;
this.threadingMaxCount=defaultThreadingMaxCount;
this.threadingWeight=defaultThreadingWeight;
this.threadingFc=defaultDisturbLineFc;
this.threadingBc=defaultDisturbLineBc;

this.draw(this.getRandomString());
}

@Override
public BufferedImage getImage() {
// TODO Auto-generated method stub
return this.image;
}


@Override
public BufferedImage next() {
// TODO Auto-generated method stub
BufferedImage image=this.image;
this.draw(this.getRandomString());
return image;
}


@Override
public String getContent() {
// TODO Auto-generated method stub
return this.content;
}


@Override
public boolean contrast(String content) {
// TODO Auto-generated method stub
return this.content.equalsIgnoreCase(content);
}


@Override
public abstract String getRandomString();


@Override
public BufferedImage draw(String content) {
// TODO Auto-generated method stub
BufferedImage image=new BufferedImage(this.width,this.height, BufferedImage.TYPE_INT_RGB);
Graphics g=image.getGraphics();
drawBackground(g);
drawString((Graphics2D)g);
drawThreading(g);
this.image=image;
return image;
}
/**
* 画出验证码的背景
* @param g
*/
public void drawBackground(Graphics g) {
Random random=new Random();
g.setColor(Color.white);
g.fillRect(0, 0,this.width,this.height);
drawLine(g);
}
/**
* 画出中穿线
* @param g
*/
public void drawThreading(Graphics g){
Random random=new Random();
int count=random.nextInt(this.threadingMaxCount+1);
for(int i=0;i<count;i++){
g.setColor(getRandColor(this.threadingFc,this.disturbLineBc));
int x1=random.nextInt(this.width/3);
int y1=random.nextInt(this.height);
int x2=x1+random.nextInt(this.threadingWeight+10);
int y2;
if(y1<=this.height/2){
y2=y1+random.nextInt(this.height/2);
}else{
y2=y1-random.nextInt(this.height/2);
}
g.drawLine(x1, y1, x2, y2);
}
}
/**
* 画出验证码内容
* @param g
*/
public void drawString(Graphics2D g){
Random random=new Random();
int x=this.leftPadding;
int y=this.topPadding;
g.setFont(this.font);
g.setColor(new Color(this.fontColorMinValue+random.nextInt(this.fontColorMaxValue),this.fontColorMinValue+random.nextInt(this.fontColorMaxValue),this.fontColorMinValue+random.nextInt(this.fontColorMaxValue)));
        for(int i=0;i<this.stringLength;i++){ 
        int dregee=new Random().nextInt()%this.maxGradient;
        g.rotate(dregee*Math.PI/180, x, y);
        g.drawString(this.content.charAt(i)+"",x,y);
        g.rotate(-dregee*Math.PI/180,x,y);
        x+=this.spaceBetween;
        }
}
/**
* 画干扰线
* @param g
*/
public void drawLine(Graphics g){
Random random = new Random();
for (int i=0;i<this.disturbLineCount;i++){
int x = random.nextInt(this.width);
int y = random.nextInt(this.height);
       int xl = random.nextInt(this.disturbLineWeight);
       int yl = random.nextInt(this.defaultDisturbLineWeight);
   g.setColor(getRandColor(this.disturbLineFc,this.disturbLineBc));
g.drawLine(x,y,x+xl,y+yl);
}
}
/**
* 产生给定范围内的随机颜色
* @param fc
* @param bc
* @return
*/
public 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);
     }


@Override
public boolean write(String formatName, OutputStream output) throws IOException{
// TODO Auto-generated method stub
return ImageIO.write(this.image, formatName, output);
}


@Override
public boolean write(String formatName, File output) throws IOException {
// TODO Auto-generated method stub
return ImageIO.write(this.image, formatName, output);
}


@Override
public boolean write(String formatName, ImageOutputStream output) throws IOException {
// TODO Auto-generated method stub
return ImageIO.write(this.image, formatName, output);
}
}



package authcode;


import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;


import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;


/**
 * 字符数字验证码
 * @author 傲世孤尘
 *
 */
public final class CharNumAuthCode extends AbstractAuthCode{
/**
* 构造方法1
*/
public CharNumAuthCode(){
this.init(defaultWidth,defaultHeight,defaultStringLength);
}
/**
* 构造方法2
* @param stringLength 验证码内容长度
*/
public CharNumAuthCode(int stringLength){
this.init(defaultWidth,defaultHeight,stringLength);
}
/**
* 构造方法3
* @param width 验证码宽度
* @param height 验证码高度
*/
public CharNumAuthCode(int width,int height){
this.init(width, height,defaultStringLength);
}
/**
* 构造方法4
* @param width 验证码宽度
* @param height 验证码高度
* @param stringLength 验证码内容长度
*/
public CharNumAuthCode(int width,int height,int stringLength){
this.init(width, height, stringLength);
}
@Override
public String getRandomString() {
// TODO Auto-generated method stub
int range=62;
String str="";
Random random=new Random();
for(int i=1;i<=this.stringLength;i++){
int t=random.nextInt(range);
if(t<=9)str+=t;
else if(t<=35)str+=(char)(t+55);
else str+=(char)(t+61);
}
this.content=str;
return str;
}
}





package authcode;


import java.awt.Font;
import java.io.UnsupportedEncodingException;
import java.util.Random;


public final class ChineseAuthCode extends AbstractAuthCode{
/**
* 构造方法1
*/
public ChineseAuthCode(){
this.init(defaultWidth,defaultHeight,defaultStringLength);
}
/**
* 构造方法2
* @param stringLength 验证码内容长度
*/
public ChineseAuthCode(int stringLength){
this.init(defaultWidth,defaultHeight,stringLength);
}
/**
* 构造方法3
* @param width 验证码宽度
* @param height 验证码高度
*/
public ChineseAuthCode(int width,int height){
this.init(width, height,defaultStringLength);
}
/**
* 构造方法4
* @param width 验证码宽度
* @param height 验证码高度
* @param stringLength 验证码内容长度
*/
public ChineseAuthCode(int width,int height,int stringLength){
this.init(width, height, stringLength);
}
public void init(int width, int height,int stringLength) {
// TODO Auto-generated method stub
this.width=width;
this.height=height;
this.stringLength=stringLength;
this.disturbLineWeight=defaultDisturbLineWeight;
this.disturbLineFc=defaultDisturbLineFc;
this.disturbLineBc=defaultDisturbLineBc;
this.disturbLineCount=100;
this.maxGradient=defaultMaxGradient;
this.topPadding=defaultTopPadding;
this.leftPadding=defaultLeftPadding;
this.spaceBetween=defaultSpaceBetween;
this.font=new Font("宋体",Font.BOLD,20);
this.fontColorMinValue=defaultFontColorMinValue;
this.fontColorMaxValue=defaultFontColorMaxValue;
this.threadingMaxCount=0;
this.threadingWeight=defaultThreadingWeight;
this.threadingFc=defaultDisturbLineFc;
this.threadingBc=defaultDisturbLineBc;

this.draw(this.getRandomString());
}
@Override
public String getRandomString() {
// TODO Auto-generated method stub
String str="";
int hightPos, lowPos; // 定义高低位
Random random = new Random();
for(int i=1;i<=this.stringLength;i++){
hightPos = (176 + Math.abs(random.nextInt(39)));//获取高位值
    lowPos = (161 + Math.abs(random.nextInt(93)));//获取低位值
    byte[] b = new byte[2];
    b[0] = (new Integer(hightPos).byteValue());
    b[1] = (new Integer(lowPos).byteValue());
    try {
str+=new String(b, "GBk");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.content=str;
return str;
}
}


基本上默认的设置就能满足需求,大家也可以根据自己需要,直接改变成员变量的值,这样就能产生满足自己需求的验证码



  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值