java 姓名校验_java实现点选汉字验证码(自己修改后的)

packagecom.rd.p2p.web;importjava.awt.BasicStroke;importjava.awt.Color;importjava.awt.Font;importjava.awt.Graphics;importjava.awt.Graphics2D;importjava.awt.geom.AffineTransform;importjava.awt.geom.Line2D;importjava.awt.image.BufferedImage;importjava.io.IOException;importjava.io.UnsupportedEncodingException;importjava.util.ArrayList;importjava.util.Arrays;importjava.util.Collections;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importjava.util.Random;importjavax.imageio.ImageIO;importjavax.servlet.ServletOutputStream;importorg.apache.commons.lang3.StringUtils;importorg.apache.poi.ss.formula.functions.T;importorg.apache.struts2.convention.annotation.Action;importcom.alibaba.fastjson.JSON;importcom.rd.p2p.additional.redisCaptcha.util.ResponseUtil;importcom.rd.p2p.common.util.redis.RedisValidImgCodeUtils;importcom.rd.p2p.core.core.Global;importcom.rd.p2p.core.core.constant.Constant;importcom.rd.p2p.core.core.web.BaseAction;public class CodeAction extends BaseAction{private static final String KEY = "randomCode";//点选文字图片验证码刷新次数

private static final String KEY_TOTAL = "select_random_code_total";//点选文字图片验证码验证通过次数

private static final String KEY_SUCC = "select_random_code_succ";//点选文字图片验证码验证失败次数

private static final String KEY_FAIL = "select_random_code_fail";//缓存时间单位秒 设置成7天

private static final int CACHE_SECONDS = 604800;//定义点选文字图片验证码允许的误差值

private static final int ERROR_AMOUNT = 12;//定义允许的误差值,单位是px//生成汉字的个数

private static Integer[] arr = new Integer[] {1, 2, 3, 4, 5};//汉字颜色随机范围

private static Color[] colors ={Color.GRAY, Color.LIGHT_GRAY, Color.CYAN};/*** 跳转页面

*@return

*/@Action("/verification")publicString verification() {

request.setAttribute("web_url", Global.getString("web_url"));return "verification";

}/**生成验证码

*@paramsrc

*@paramx

*@paramy*/@Action("/code/getVerificationCode")public voidreadUsingImageReaderBigcH() {

ServletOutputStream outStream= null;try{// http://localhost:8080/gtop/img/149679.jpg//String url = "d:/4.png";//url = request.getSession().getServletContext().getRealPath("") + url;

/*InputStream source = new FileInputStream(src);

BufferedImage image = null;

image = ImageIO.read(source);*/

//生成背景图片

BufferedImage image =getBackGround();int hight =image.getHeight();

Graphics graphics=image.getGraphics();//设置颜色

graphics.setColor(Color.red);

graphics.setFont(new Font("宋体", Font.BOLD, 30));

StringBuilder sb= newStringBuilder();

Random random= newRandom();//转成集合

List intList =Arrays.asList(arr);//重新随机排序

Collections.shuffle(intList);//list参数坐标参数 用于校验是否验证通过

List codeList = new ArrayList();int x = 0;int y = 0;//定义随机1到arr.length某一个字不参与校验

int num = random.nextInt(arr.length)+1;for (int i = 0; i < arr.length; i++) { //5个汉字,只点4个

String ch =getRandomChineseChar();int place =intList.get(i);if (place == 1) {

x= new Random().nextInt(30) + 40; //自己定义的位子坐标

y = new Random().nextInt(30) + 40; //i=1的时候,y的值

}if (place == 2) {

x= new Random().nextInt(40) + 120; //自己定义的位子坐标

y = new Random().nextInt(30) + 50; //i=2的时候,y的值

}if (place == 3) {

x= new Random().nextInt(70) + 200; //自己定义的位子坐标

y = new Random().nextInt(50) + 100; //i=3的时候,y的值

}if (place == 4) {

x= new Random().nextInt(70) + 80; //i=4的时候,x的值

y = new Random().nextInt(30) + 90; //自己定义的位子坐标

}if (place == 5) {

x= new Random().nextInt(70) + 180; //i=4的时候,x的值

y = new Random().nextInt(30) + 50; //自己定义的位子坐标

}

Constant.LOGGER.info("x:" + x + ",y:" + y + ",hight:" +hight);//字体颜色

graphics.setColor(colors[random.nextInt(colors.length)]);

graphics.drawString(ch, x, y);if (place !=num) {

sb.append(ch);

codeList.add(x+ "_" + y); //jsp页面坐标原点在字的中间,drawString方法坐标原点在中间

}

}

Constant.LOGGER.info("汉字:" +sb);//放入session//将产生的随机汉字验证码存进session中进行保存

String sessionid =request.getSession().getId();

RedisValidImgCodeUtils.save(sessionid+KEY, codeList);//增加验证码请求次数

RedisValidImgCodeUtils.increment(KEY_TOTAL, CACHE_SECONDS);//可以将图片合并传入前端 也可以直接传数据汉字给前端//创建顶部图片

BufferedImage bi = new BufferedImage(image.getWidth(), 25, BufferedImage.TYPE_INT_RGB);

Graphics gra=bi.getGraphics();//设置背景颜色

gra.setColor(Color.WHITE);//填充区域

gra.fillRect(0, 0, bi.getWidth(), bi.getHeight());//设置边框颜色

gra.setColor(Color.BLUE);//设置边框区域

gra.drawRect(1, 1, bi.getWidth() - 2, bi.getHeight() - 2);//设置文字背景颜色

Font font = new Font("Microsoft YaHei", Font.BOLD, 16);

gra.setFont(font);

gra.setColor(Color.BLACK);

gra.drawString("按顺序点击:" + sb.toString(), (bi.getWidth() - 10*font.getSize())/2, bi.getHeight()/2 + font.getSize()/2);//设置文字字体 与位子 居中

BufferedImage combined= new BufferedImage(image.getWidth(), image.getHeight() +bi.getHeight(), BufferedImage.TYPE_INT_RGB);

Graphics g= combined.getGraphics(); //合并

g.drawImage(bi, 0, 0, null);

g.drawImage(image,0, bi.getHeight(), null);

outStream=response.getOutputStream();

ImageIO.write(combined,"jpg", outStream);

}catch(IOException e) {

e.printStackTrace();

}finally{try{if (outStream != null) {

outStream.close();

}

}catch(IOException e) {

e.printStackTrace();

}

}

}

@Action("/code/verify")public void verify() throwsIOException {

Map data = new HashMap();

data.put("result", false);

String value= request.getParameter("code");

String sessionid=request.getSession().getId();if (RedisValidImgCodeUtils.get(sessionid + KEY) == null) {

printWebJson(JSON.toJSONString(data));return;

}

List sValue = (List) RedisValidImgCodeUtils.get(sessionid +KEY);//取到数据后直接清掉redis

RedisValidImgCodeUtils.del(sessionid +KEY);

Constant.LOGGER.info("**前端请求数据***"+value);

Constant.LOGGER.info("**后端实际数据**"+sValue.toString());//为null 或者"" 或者 " "

if (StringUtils.isBlank(value) || sValue == null || sValue.size() < 1) {

printWebJson(JSON.toJSONString(data));return;

}

String [] valueStr= value.split(",");if(valueStr.length != sValue.size() || valueStr.length != 4){

printWebJson(JSON.toJSONString(data));return;

}/*判断坐标参数是否正确*/String str= "";for (int i = 0; i < valueStr.length; i++) {

str=valueStr[i].toString();if(StringUtils.isBlank(str) ||StringUtils.isBlank(sValue.get(i).toString())){

printWebJson(JSON.toJSONString(data));return;

}

String [] vL= valueStr[i].toString().split("_");

String [] svL= sValue.get(i).toString().split("_");if(vL.length != svL.length || svL.length != 2){

printWebJson(JSON.toJSONString(data));return;

}//x轴 y轴判断 坐标点在左上角 ,图片宽度30px 点击范围扩大12px, 范围在 x-13 < x

if(!(Integer.parseInt(svL[0])-ERROR_AMOUNT < Integer.parseInt(vL[0])-15 && Integer.parseInt(vL[0])-15 < Integer.parseInt(svL[0])+ERROR_AMOUNT )|| !(Integer.parseInt(svL[1])-ERROR_AMOUNT < Integer.parseInt(vL[1])-15 && Integer.parseInt(vL[1])-15 < Integer.parseInt(svL[1])+ERROR_AMOUNT)){//增加验证失败次数

RedisValidImgCodeUtils.increment(KEY_FAIL, CACHE_SECONDS);

printWebJson(JSON.toJSONString(data));return;

}

}//增加验证通过次数

RedisValidImgCodeUtils.increment(KEY_SUCC, CACHE_SECONDS);

data.put("result", true);

printWebJson(JSON.toJSONString(data));

}/*** 生成背景图片

*@return

*/

publicBufferedImage getBackGround(){int width=300; //指定生成验证码的宽度

int height=200; //指定生成验证码的高度

BufferedImage image = newBufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

Graphics g=image.getGraphics();

Graphics2D g2d= (Graphics2D)g; //创建Graphics2D对象

Random random = newRandom();//Font mFont = new Font("黑体", Font.BOLD, 16);//定义字体样式//g.setColor(getRandColor(200, 250));//背景色

g.fillRect(0, 0, width, height); //绘制背景//g.setFont(mFont);//设置字体

g.setColor(getRandColor(180, 200)); //线条色//绘制88根位置和颜色全部为随机产生的线条,该线条为2f

for (int i = 0; i < 88; i++) {int x = random.nextInt(width-1);int y = random.nextInt(height-1);int x1 = random.nextInt(100)+1;int y1 = random.nextInt(120)+1;

BasicStroke bs= newBasicStroke(2f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL);

Line2D line= new Line2D.Double(x,y,x+x1,y+y1);

g2d.setStroke(bs);

g2d.draw(line);//绘制直线//g2d.setColor(getRandColor(random, 30, 150));//随机每条线条的颜色

}//输出生成的验证码图片

g.dispose();returnimage;

}private static Color getRandColor(Random random, int fc, intbc){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 newColor(r, g, b);

}private staticString[] generateCheckCode() {

String[] res= new String[2];

Random random= newRandom();intintTemp;int intFirst = random.nextInt(100);int intSec = random.nextInt(100);

String checkCode= "";int result = 0;switch (random.nextInt(6)) {case 0:if (intFirst

intTemp=intFirst;

intFirst=intSec;

intSec=intTemp;

}

checkCode= intFirst + " - " + intSec + " = ?";

result= intFirst-intSec;break;case 1:if (intFirst

intTemp=intFirst;

intFirst=intSec;

intSec=intTemp;

}

checkCode= intFirst + " - ? = "+(intFirst-intSec);

result=intSec;break;case 2:if (intFirst

intTemp=intFirst;

intFirst=intSec;

intSec=intTemp;

}

checkCode= "? - "+intSec+" = "+(intFirst-intSec);

result=intFirst;break;case 3:

checkCode= intFirst + " + " + intSec + " = ?";

result= intFirst +intSec;break;case 4:

checkCode= intFirst + " + ? ="+(intFirst+intSec);

result=intSec;break;case 5:

checkCode= "? + " + intSec + " ="+(intFirst+intSec);

result=intFirst;break;

}

res[0] =checkCode;

res[1] =String.valueOf(result);

Constant.LOGGER.info("result=" +result);returnres;

}

@Action("/code/calc")public void calcCode() throwsIOException{int width = 140, height = 37;try{

BufferedImage image= newBufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

Graphics g=image.getGraphics();

Random random= newRandom();

g.setColor(getRandColor(random,200, 250));

g.fillRect(0, 0, width, height);

String[] fontTypes= { "\u5b8b\u4f53", "\u65b0\u5b8b\u4f53", "\u9ed1\u4f53", "\u6977\u4f53", "\u96b6\u4e66"};int fontTypesLength =fontTypes.length;

g.setColor(getRandColor(random,160, 200));

g.setFont(new Font("Times New Roman", Font.PLAIN, 14 + random.nextInt(6)));for (int i = 0; i < 255; i++) {int x =random.nextInt(width);int y =random.nextInt(height);int xl = random.nextInt(12);int yl = random.nextInt(12);

g.drawLine(x, y, x+ xl, y +yl);

}

String[] result=generateCheckCode();

RedisValidImgCodeUtils.save(request.getSession().getId()+ "calc_code", result[1]);

String [] baseChar= result[0].split(" ");for (int i = 0; i < baseChar.length; i++) {

g.setColor(getRandColor(random,30, 150));

g.setFont(new Font(fontTypes[random.nextInt(fontTypesLength)], Font.BOLD, 22 + random.nextInt(6)));

g.drawString(baseChar[i],24 * i + 10, 24);

}

g.dispose();//发送图片

ResponseUtil.sendImg(response, image, "image/jpeg", "code", "jpg");

}catch(IllegalStateException e) {

Constant.LOGGER.error(e.getMessage());

e.printStackTrace();

}

}

@Action("/code/getRandomCode")public void getRandomCode() throwsIOException{//TODO Auto-generated method stub//设置不缓存图片

response.setHeader("Pragma", "No-cache");

response.setHeader("Cache-Control", "No-cache");

response.setDateHeader("Expires", 0);//指定生成的响应图片

response.setContentType("image/jpeg");int width=140; //指定生成验证码的宽度

int height=37; //指定生成验证码的高度

BufferedImage image = newBufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

Graphics g=image.getGraphics();

Graphics2D g2d= (Graphics2D)g; //创建Graphics2D对象

Random random = newRandom();

Font mFont= new Font("黑体", Font.BOLD, 22); //定义字体样式

g.setColor(getRandColor(200, 250));

g.fillRect(0, 0, width, height); //绘制背景

g.setFont(mFont); //设置字体

g.setColor(getRandColor(180, 200));//绘制100根位置和颜色全部为随机产生的线条,该线条为2f

for (int i = 0; i < 100; i++) {int x = random.nextInt(width-1);int y = random.nextInt(height-1);int x1 = random.nextInt(6)+1;int y1 = random.nextInt(12)+1;

BasicStroke bs= newBasicStroke(2f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL);

Line2D line= new Line2D.Double(x,y,x+x1,y+y1);

g2d.setStroke(bs);

g2d.draw(line);//绘制直线

}//输出由英文,数字和中文随机组成的验证文字,具体的组合方式根据生成随机数确定

String sRand = "";//输出随机的验证文字

String ctmp = "";int itmp = 0;for(int i = 0;i<4;i++){switch (random.nextInt(2)) {case 0:

itmp= random.nextInt(26)+65; //生成A~Z的字母

ctmp = String.valueOf((char)itmp);break;default:

ctmp= String.valueOf(random.nextInt(8)+2); //生成2~9的数字

break;

}

sRand+=ctmp;

Color color= new Color(20+random.nextInt(110), 20+random.nextInt(110), 20+random.nextInt(110));

g.setColor(color);//将生成的随机数进行随机缩放病旋转指定角度//将文字旋转指定角度

Graphics2D g2d_word =(Graphics2D)g;

AffineTransform trans= newAffineTransform();

trans.rotate(random.nextInt(45)*3.14/180, 15*i+8, 7);//缩放文字

/*float scaleSize = random.nextFloat()+0.8f;

if(scaleSize > 1f){

scaleSize = 1f;

}

trans.scale(scaleSize, scaleSize);*/g2d_word.setTransform(trans);

g.drawString(ctmp,20*i+18, 18); //每个字的间距xy

}//将生成的验证码保存道session中

RedisValidImgCodeUtils.save(request.getSession().getId() + "randCheckCode", sRand);//输出生成的验证码图片

g.dispose();

ImageIO.write(image,"JPEG", response.getOutputStream());

}public Color getRandColor(int s,inte){

Random random= newRandom();if(s>255)s = 255;if(e>255)e = 255;int r = s+random.nextInt(e-s);int g = s+random.nextInt(e-s);int b = s+random.nextInt(e-s);return newColor(r, g, b);

}public staticString getRandomChineseChar() {

String str= null;inths, ls;

Random random= newRandom();

hs= (176 + Math.abs(random.nextInt(39)));

ls= (161 + Math.abs(random.nextInt(93)));byte[] b = new byte[2];

b[0] = (newInteger(hs).byteValue());

b[1] = (newInteger(ls).byteValue());try{

str= new String(b, "GBk"); //转成中文

} catch(UnsupportedEncodingException ex) {

ex.printStackTrace();

}returnstr;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值