JCaptcha算数式验证码
前两天买了张火车票,使人egg碎的验证已无力吐槽,试了几次都让我开始怀疑我的IQ是否是合适再从事程序猿的这个”神圣的职业“了。今天分享的是1段比较传统而不失实用的验证,验证的意义想必大家都已知晓。 好了,语言总是苍白无力。直入真题来看代码的实现的吧。 操作环境: 主要分为几个步骤 1、生成图片package com.tgb.cfl;
import com.octo.captcha.service.captchastore.FastHashMapCaptchaStore;
import com.octo.captcha.service.image.DefaultManageableImageCaptchaService;
import com.octo.captcha.service.image.ImageCaptchaService;
public class BfferImageCss {
private static DefaultManageableImageCaptchaService instance=null;
public static int result;
/**
* 单例模式的类用于生成图片
* @return
*/
public static ImageCaptchaService getInstance() {
VerifImage vi= new VerifImage();
result=vi.getResult();
if(instance==null){
instance = new DefaultManageableImageCaptchaService(new FastHashMapCaptchaStore(),vi,180,100000,75000);
}else{
instance.setCaptchaEngine(vi);
}
return instance;
}
}
2、设置图片样式、字体情势、操作符情势 package com.tgb.cfl;
import java.awt.*;
import java.util.Random;
import com.octo.captcha.component.image.backgroundgenerator.BackgroundGenerator;
import com.octo.captcha.component.image.backgroundgenerator.FunkyBackgroundGenerator;
import com.octo.captcha.component.image.color.ColorGenerator;
import com.octo.captcha.component.image.color.RandomRangeColorGenerator;
import com.octo.captcha.component.image.fontgenerator.FontGenerator;
import com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;
import com.octo.captcha.component.image.textpaster.TextPaster;
import com.octo.captcha.component.image.textpaster.RandomTextPaster;
import com.octo.captcha.component.image.wordtoimage.WordToImage;
import com.octo.captcha.component.image.wordtoimage.ComposedWordToImage;
import com.octo.captcha.component.word.wordgenerator.DummyWordGenerator;
import com.octo.captcha.component.word.wordgenerator.WordGenerator;
import com.octo.captcha.engine.image.ListImageCaptchaEngine;
import com.octo.captcha.image.gimpy.GimpyFactory;
public class VerifImage extends ListImageCaptchaEngine {
static{
System.setProperty("java.awt.headless","true");
}
//壹 贰 叁 肆 伍 陆 柒 捌 玖
private final static String[] nods={"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
//1,2,3,4,5,6,7,8,9
private final static String[] nohs={"零","1","2","3","4","5","6","7","8","9"};
//0 1 2 3 4 5 6 7 8 9
private final static String[] noss={"0","9"};
// 寄存加减乘运算符
private final static char[] arr = {'+','-','×'};
//汉字加减乘运算符
private final static char[] arrh={'加','减','乘'};
private StringBuffer sb=null;
private Random random=null;
private int result;
public int getResult(){
return result;
}
@Override
protected void buildInitialFactories() {
random = new Random();
sb=new StringBuffer();
//获得1个随机boolean
boolean bool=random.nextBoolean();
//掉用生成运算模式方法
this.model(bool);
int len=sb.toString().length();
WordGenerator wgen=new DummyWordGenerator(sb.toString());
//设置字体色彩
RandomRangeColorGenerator cgen = new RandomRangeColorGenerator(new int[]{0,60},new int[]{0,60});
// 文字显示的个数
TextPaster textPaster = new RandomTextPaster(len,len,cgen,true);
//设置图片背景色彩
ColorGenerator colorGenerator = new RandomRangeColorGenerator(new int[]{200,200},new int[]{200,200});
// 图片的大小
BackgroundGenerator backgroundGenerator = new FunkyBackgroundGenerator(90,28,colorGenerator);
// 字体魄式
Font[] fontsList = new Font[]{new Font("宋体",0,10)};
// 文字的大小
FontGenerator fontGenerator = new RandomFontGenerator(18,20,fontsList);
//将文字写入到图片中
WordToImage wordToImage = new ComposedWordToImage(fontGenerator,backgroundGenerator,textPaster);
this.addFactory(new GimpyFactory(wgen,wordToImage));
}
private void model(boolean bool){
// 生成随机整数num1
int num1 = getRandomNum();
// 生成随机整数num2
int num2 = getRandomNum();
//随机产生运算方式
int operate = random.nextInt(3);
switch (operate) {
case 0:
this.result = num1 + num2;
break;
case 1:
this.result = num1 - num2;
break;
case 2:
this.result = num1 * num2;
break;
}
try{
//随机生成运算表达试
if(bool){
this.getRes(operate,num1,num2);
}else{
int r=random.nextInt(3);
sb.append(getNos(r,num1)+" ");
r=random.nextInt(2);
sb.append(getOperate(r,operate)+" ");
r=random.nextInt(3);
sb.append(getNos(r,num2));
sb.append(" = ?");
}
}catch (Exception e){
e.printStackTrace();
}
}
//生成运算表达试
private void getRes(int operate,int num1,int num2){
int r=random.nextInt(2);
switch (r){
case 0:
r=random.nextInt(3);
sb.append(getNos(r,operate)+" ");
sb.append("?");
sb.append(" = "+this.result);
this.result=num2;
break;
case 1:
sb.append("? ");
r=random.nextInt(2);
sb.append(getOperate(r,num2));
sb.append(" = "+this.result);
this.result=num1;
break;
}
}
//获得运算数字
private String getNos(int random,int num) {
switch (random){
case 0:
return nods[num];
case 1:
return nohs[num];
case 2:
return noss[num];
}
return null;
}
//获得运算符
private String getOperate(int random,int num){
switch (random){
case 0:
return String.valueOf(arr[num]);
case 1:
return String.valueOf(arrh[num]);
}
return null;
}
//获得0~9随机数
private int getRandomNum(){
int num = random.nextInt(10);
while (num == 0) {
num = random.nextInt(10);
}
return num;
}
}
这里主要是为了构成用于计算结果的文字和图片和1些样式的设定。 3、测实验证码 servlet package com.tgb.cfl;
import com.octo.captcha.service.CaptchaServiceException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* 用于生产验证码图片的class
* @author cfl
* @date 2015年4月30日
*
*/
public class VerificationCode extends HttpServlet {
private static final long serialVersionUID = -11L;
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
}
public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException {
byte[] b = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
//获得session对象
HttpSession session=request.getSession();
//获得本次会话的sessionID
String captchaId = session.getId();
//生成图片
BufferedImage challenge = BfferImageCss.getInstance().getImageChallengeForID(captchaId,request.getLocale());
//将结果保存到session
session.setAttribute(captchaId+"_vccode",BfferImageCss.result);
//加密
JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(baos);
jpegEncoder.encode(challenge);
} catch (IllegalArgumentException e) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
} catch (CaptchaServiceException e) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
b = baos.toByteArray();
//设置相应的参数,用于显示图片
response.setHeader("Cache-Control","no-store");
response.setHeader("Pragma","no-cache");
response.setDateHeader("Expires",0);
response.setContentType("image/jpeg");
ServletOutputStream sos = response.getOutputStream();
sos.write(b);
sos.flush();
sos.close();
}
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
doPost(request,response);
}
}
这里是1个简单的servlet用于,虽然是1个简单的servlet,但是也足够完成所需功能。 好了,最后附上效果图1张 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |