图形验证码的java通用类
在应用程序中为防止系统被攻击程序自动访问,通常提供一个人眼容易识别,但程序很难识别的图形,图形内是随机产生的一些字符。为防止被攻击程序自动识别,字符通常会在位置和颜色上作随机处理。为便于使用,本人用 java实现了一个生成随机字符图片的通用类,封装了生成过程的复杂性,能非常方便的使用。实现类类名为RandomGraphic,它由一个静态工厂方法createInstance(int charCount)来创建对象实例,charCount指定图片中字符的个数,最多16个。提供了两个方法来生成随机图片,一个方法String drawNumber(String graphicFormat,OutputStream out) 生成的图片中都是随机数字,由0-9组成。另一个方法String drawAlpha(String graphicFormat,OutputStream out)生成的图片中都是随机字母,由a-z组成,生成的字符个数在工厂方法中指定。将数字和图片分开是因为有些数字和字母人眼看上去很难区分,反而影响用户输入。graphicFormat为生成图片格式,取常量值GRAPHIC_JPEG 或 GRAPHIC_PNGout用来输出生成的图片文件内容,可以是一个文件,或servlet中输出到客户端的流,以便于在页面显示。下面给出原码和在servlet中的示例代码。package net;import java.awt.Color;import java.awt.Font;import java.awt.Graphics2D;import java.awt.image.BufferedImage;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.util.Random;import javax.imageio.ImageIO;/*** 生成随机数字或字母串,以图像方式显示,用于人工识别,使程序很难识别。* 减小系统被程序自动攻击的可能性。* 生成的图形颜色由红、黑、蓝、紫4中随机组合而成,数字或字母垂直方向位置在* 一定范围内也是随机的,减少被程序自动识别的几率。* 由于数字的0,1,2易和字母的o,l,z混淆,使人眼难以识别,因此不生成数字* 和字母的混合串。* 生成的串字母统一用小写,串的最大长度为16。** @version* @Since* @See Also* @author lchen* Create Date 2005-12-16**/public class RandomGraphic {//字符的高度和宽度,单位为像素private int wordHeight = 10;private int wordWidth = 15;//字符大小private int fontSize = 16;//最大字符串个数private static final int MAX_CHARCOUNT = 16;//垂直方向起始位置private final int initypos = 5;//要生成的字符个数,由工厂方法得到private int charCount = 0;//颜色数组,绘制字串时随机选择一个private static final Color[] CHAR_COLOR = {Color.RED,Color.BLUE,Color.GREEN,Color.MAGENTA};//随机数生成器private Random r = new Random();/*** 生成图像的格式常量,JPEG格式,生成为文件时扩展名为.jpg;* 输出到页面时需要设置MIME type 为image/jpeg*/public static String GRAPHIC_JPEG = "JPEG";/*** 生成图像的格式常量,PNG格式,生成为文件时扩展名为.png;* 输出到页面时需要设置MIME type 为image/png*/public static String GRAPHIC_PNG = "PNG";//用工厂方法创建对象protected RandomGraphic(int charCount){this.charCount = charCount;}/*** 创建对象的工厂方法* @param charCount 要生成的字符个数,个数在1到16之间** Return 返回RandomGraphic对象实例* @throws Exception 参数charCount错误时抛出*/public static RandomGraphic createInstance(int charCount) throws Exception{if (charCount < 1 || charCount > MAX_CHARCOUNT){throw new Exception("Invalid parameter charCount,charCount should between in 1 and 16");}return new RandomGraphic(charCount);}/*** 随机生成一个数字串,并以图像方式绘制,绘制结果输出到流out中** @param graphicFormat 设置生成的图像格式,值为GRAPHIC_JPEG或GRAPHIC_PNG* @param out 图像结果输出流* @return 随机生成的串的值* @throws IOException*/public String drawNumber(String graphicFormat,OutputStream out) throws IOException{// 随机生成的串的值String charValue = "";charValue = randNumber();return draw(charValue,graphicFormat,out);}/*** 随机生成一个字母串,并以图像方式绘制,绘制结果输出到流out中** @param graphicFormat 设置生成的图像格式,值为GRAPHIC_JPEG或GRAPHIC_PNG* @param out 图像结果输出流* @return 随机生成的串的值* @throws IOException*/public String drawAlpha(String graphicFormat,OutputStream out) throws IOException{// 随机生成的串的值String charValue = "";charValue = randAlpha();return draw(charValue,graphicFormat,out);}/*** 以图像方式绘制字符串,绘制结果输出到流out中* @param charValue 要绘制的字符串* @param graphicFormat 设置生成的图像格式,值为GRAPHIC_JPEG或GRAPHIC_PNG* @param out 图像结果输出流* @return 随机生成的串的值* @throws IOException*/protected String draw(String charValue,String graphicFormat,OutputStream out) throws IOException{//计算图像的宽度和高度int w = (charCount+2) * wordWidth;int h = wordHeight * 3;//创建内存图像区BufferedImage bi = new BufferedImage(w,h,BufferedImage.TYPE_3BYTE_BGR);Graphics2D g = bi.createGraphics();//设置背景色Color backColor = Color.WHITE;g.setBackground(backColor);g.fillRect(0,0,w,h);//设置fontg.setFont(new Font(null,Font.BOLD,fontSize));//绘制charValue,每个字符颜色随机for(int i = 0; i < charCount; i++){String c = charValue.substring(i,i+1);Color color = CHAR_COLOR[randomInt(0,CHAR_COLOR.length)];g.setColor(color);int xpos = (i+1) * wordWidth;//垂直方向上随机int ypos = randomInt(initypos+wordHeight,initypos+wordHeight*2);g.drawString(c,xpo补充:软件开发 , Java ,
上一个:简单的Java连接数据库
下一个:编程之美_005背包问题
- 更多JAVA疑问解答:
- java怎么在线读取ftp服务器上的文件内容
- 关于程序员的职业规划
- HTML和JSP矛盾吗?
- java小程序如何打包?
- java怎么split路径文件名?
- jsp+javaBean中Column 'ordersPrice' specified twice的错误
- Java TCP/IP Socket网络编程系列
- 大家来讨论一下我到底该用什么好?Swing 还是 JavaFX
- 关于Hibernate实体自身多对一的抓取问题
- 关于apache2+tomcat群集出现的问题
- spring 获取上下文问题
- SSH 导入导出excel 谁有这块的资料吗?
- Ext TreePanel 刷新问题
- springmvc 加载一个jsp页面执行多个方法 报404
- checkbox数组action怎么向页面传值