JAVA中的验证码生成

生成验证码的工具类:VerifyCodeUtils(有几种实现方式,放入流,保存文件等)

public class VerifyCodeUtils {

//使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
private static Random random = new Random(); 

/**
* 使用系统默认字符源生成验证码
* @param verifySize 验证码长度
* @return
*/
public static String generateVerifyCode(int verifySize){
return generateVerifyCode(verifySize, VERIFY_CODES);
}
/**
* 使用指定源生成验证码
* @param verifySize 验证码长度
* @param sources 验证码字符源
* @return
*/
public static String generateVerifyCode(int verifySize, String sources){
if(sources == null || sources.length() == 0){
sources = VERIFY_CODES;
}
int codesLen = sources.length();
Random rand = new Random(System.currentTimeMillis());
StringBuilder verifyCode = new StringBuilder(verifySize);
for(int i = 0; i < verifySize; i++){
verifyCode.append(sources.charAt(rand.nextInt(codesLen-1)));
}
return verifyCode.toString();
} 

/**
* 生成随机验证码文件,并返回验证码值
* @param w
* @param h
* @param outputFile
* @param verifySize
* @return
* @throws IOException
*/
public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException{
String verifyCode = generateVerifyCode(verifySize);
outputImage(w, h, outputFile, verifyCode);
return verifyCode;
} 

/**
* 输出随机验证码图片流,并返回验证码值
* @param w
* @param h
* @param os
* @param verifySize
* @return
* @throws IOException
*/
public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException{
String verifyCode = generateVerifyCode(verifySize);
outputImage(w, h, os, verifyCode);
return verifyCode;
} 

/**
* 生成指定验证码图像文件
* @param w
* @param h
* @param outputFile
* @param code
* @throws IOException
*/
public static void outputImage(int w, int h, File outputFile, String code) throws IOException{
if(outputFile == null){
return;
}
File dir = outputFile.getParentFile();
if(!dir.exists()){
dir.mkdirs();
}
try{
outputFile.createNewFile();
FileOutputStream fos = new FileOutputStream(outputFile);
outputImage(w, h, fos, code);
fos.close();
} catch(IOException e){
throw e;
}
} 

/**
* 输出指定验证码图片流
* @param w
* @param h
* @param os
* @param code
* @throws IOException
*/
public static void outputImage(int w, int h, OutputStream os,String code)throwsIOException{
int verifySize = code.length();
BufferedImage image =newBufferedImage(w, h,BufferedImage.TYPE_INT_RGB);
Random rand =newRandom();
Graphics2D g2 = image.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
Color[] colors =newColor[5];
Color[] colorSpaces =newColor[]{Color.WHITE,Color.CYAN,
Color.GRAY,Color.LIGHT_GRAY,Color.MAGENTA,Color.ORANGE,
Color.PINK,Color.YELLOW };
float[] fractions =newfloat[colors.length];
for(int i =0; i < colors.length; i++){
colors[i]= colorSpaces[rand.nextInt(colorSpaces.length)];
fractions[i]= rand.nextFloat();
}
Arrays.sort(fractions);

g2.setColor(Color.GRAY);// 设置边框色
g2.fillRect(0,0, w, h);

Color c = getRandColor(200,250);
g2.setColor(c);// 设置背景色
g2.fillRect(0,2, w, h-4);

//绘制干扰线
Random random =newRandom();
g2.setColor(getRandColor(160,200));// 设置线条的颜色
for(int i =0; i <20; i++){
int x = random.nextInt(w -1);
int y = random.nextInt(h -1);
int xl = random.nextInt(6)+1;
int yl = random.nextInt(12)+1;
g2.drawLine(x, y, x + xl +40, y + yl +20);
}

// 添加噪点
float yawpRate =0.05f;// 噪声率
int area =(int)(yawpRate * w * h);
for(int i =0; i < area; i++){
int x = random.nextInt(w);
int y = random.nextInt(h);
int rgb = getRandomIntColor();
image.setRGB(x, y, rgb);
}

shear(g2, w, h, c);// 使图片扭曲 

g2.setColor(getRandColor(100,160));
int fontSize = h-4;
Font font =newFont("Algerian",Font.ITALIC, fontSize);
g2.setFont(font);
char[] chars = code.toCharArray();
for(int i =0; i < verifySize; i++){
AffineTransform affine =newAffineTransform();
affine.setToRotation(Math.PI /4* rand.nextDouble()*(rand.nextBoolean()?1:-1),(w / verifySize)* i + fontSize/2, h/2);
g2.setTransform(affine);
g2.drawChars(chars, i,1,((w-10)/ verifySize)* i +5, h/2+ fontSize/2-10);
}

g2.dispose();
ImageIO.write(image,"jpg", os);

}

privatestaticColor getRandColor(int fc,int bc){
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);
returnnewColor(r, g, b);
}

privatestaticint getRandomIntColor(){
int[] rgb = getRandomRgb();
int color =0;
for(int c : rgb){
color = color <<8;
color = color | c;
}
return color;
}

privatestaticint[] getRandomRgb(){
int[] rgb =newint[3];
for(int i =0; i <3; i++){
rgb[i]= random.nextInt(255);
}
return rgb;
}

privatestaticvoid shear(Graphics g,int w1,int h1,Color color){
shearX(g, w1, h1, color);
shearY(g, w1, h1, color);
}

privatestaticvoid shearX(Graphics g,int w1,int h1,Color color){

int period = random.nextInt(2);

boolean borderGap =true;
int frames =1;
int phase = random.nextInt(2);

for(int i =0; i < h1; i++){
double d =(double)(period >>1)
*Math.sin((double) i /(double) period
+(6.2831853071795862D*(double) phase)
/(double) frames);
g.copyArea(0, i, w1,1,(int) d,0);
if(borderGap){
g.setColor(color);
g.drawLine((int) d, i,0, i);
g.drawLine((int) d + w1, i, w1, i);
}
}

}

privatestaticvoid shearY(Graphics g,int w1,int h1,Color color){

int period = random.nextInt(40)+10;// 50; 

boolean borderGap =true;
int frames =20;
int phase =7;
for(int i =0; i < w1; i++){
double d =(double)(period >>1)
*Math.sin((double) i /(double) period
+(6.2831853071795862D*(double) phase)
/(double) frames);
g.copyArea(i,0,1, h1,0,(int) d);
if(borderGap){
g.setColor(color);
g.drawLine(i,(int) d, i,0);
g.drawLine(i,(int) d + h1, i, h1);
}

}

}
publicstaticvoid main(String[] args)throwsIOException{
File dir =newFile("c:/verifies");
int w =200, h =80;
// for(int i = 0; i < 50; i++){
String verifyCode = generateVerifyCode(4);
File file =newFile(dir, verifyCode +".jpg");
outputImage(w, h, file, verifyCode);
// }
}
}

2.servlet:CaptchaServlet

public class CaptchaServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
//(先生成字符串保存,然后在把字符串绘制到图画)
//生成随机字串
String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
//存入会话session
HttpSession session = request.getSession(true);
DoradoContext context = DoradoContext.getCurrent();
session.setAttribute("code", verifyCode.toLowerCase());
//生成图片
int w = 120, h = 30;
VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode);
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}

4.web.xml

<servlet-mapping>
<servlet-name>doradoServlet</servlet-name>
<url-pattern>/dorado/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>CaptchaServlet</servlet-name>
<url-pattern>/servlet/CaptchaServlet</url-pattern>
</servlet-mapping>

5.调用

<div class="input-append">
<input id="captcha" type="text" name="j_captcha" />
<div class="add-on">
<img id="captchaImage"  src="servlet/CaptchaServlet" />
</div>
</div>
时间: 2024-08-25 16:32:33

JAVA中的验证码生成的相关文章

Java中使用验证码和二维码

资源 需要:   jelly-core-1.7.0.GA.jar 网站:   http://lychie.github.io/products.html 将下载下来的 jelly-core-1.7.0.GA.jar 丢到项目里,不需要编写任何 java 代码,只需要在项目的 web.xml 文件中配置相关信息即可. 验证码 基于 Servlet 实现,在 web.xml 中配置即可使用.并支持自定义样式,常用的配置项见下表: 属性名称 属性描述 默认值 可选值 border 边框 no no,y

Java中的验证码实现

实例: /** * Created by hzllb */ import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.HashMap; import ja

Java中使用OpenSSL生成的RSA公私钥进行数据加解密

RSA是什么:RSA公钥加密算法是1977年由Ron Rivest.Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的.RSA取名来自开发他们三者的名字.RSA是目前最有影响力的公钥加密算法,它能够 抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准.目前该加密方式广泛用于网上银行.数字签名等场合.RSA算法基于一个十分简单的 数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥. OpenSSL是什

Java中使用OpenSSL生成的RSA公私钥

RSA是什么:RSA公钥加密算法是1977年由Ron Rivest.Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的.RSA取名来自开发他们三者的名字.RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准.目前该加密方式广泛用于网上银行.数字签名等场合.RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥. OpenSSL是什么:众

在JAVA中使用JSONObject生成json

JSON是一种轻量级的数据交换格式,在现在的web开发中,是非常常见的.在没有方便的工具之前,我们或许会使用拼字符串的形式来生成json数组,今天我们使用一个json-lib.jar包来为我们实现生成json的功能. 所必须的包有: commons-httpclient-3.1.jar commons-lang-2.4.jar commons-logging-1.1.1.jar json-lib-2.4-jdk15.jar ezmorph-1.0.6.jar commons-collection

Java中的反射机制(一)

基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象的方法的功能来自于Java语言的反射(Reflection)机制. Java反射机制主要提供了以下功能: 1.在运行时判断任意一个对象所属的类. 2.在运行时构造任意一个类的对象. 3.在运行时判断任意一个类所具有的成员变量和方法. 4.在运行时调用任意一个对象的方法. Reflection是Java被视为动态(或准动

java中的反射机制(一)-----转载

Java 反射机制 基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象的方法的功能来自于Java语言的反射(Reflection)机制. Java反射机制主要提供了以下功能: 1.在运行时判断任意一个对象所属的类. 2.在运行时构造任意一个类的对象. 3.在运行时判断任意一个类所具有的成员变量和方法. 4.在运行时调用任意一个对象的方法. Reflection是Jav

Java技术 | 细谈Java中UUID的简单了解与使用

什么是UUID? UUID全称:Universally Unique Identifier,即通用唯一识别码. UUID是由一组32位数的16进制数字所构成,是故UUID理论上的总数为16^32 = 2^128,约等于3.4 x 10^38.也就是说若每纳秒产生1兆个UUID,要花100亿年才会将所有UUID用完. UUID的标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的32个字符,如:550e8400-e29b-41d4-a716-446655440000. U

SpringMvc项目中使用GoogleKaptcha 生成验证码

SpringMvc项目中使用GoogleKaptcha 生成验证码 前言:google captcha 是google生成验证码的一个工具类,其原理是将随机生成字符串保存到session中,同时以图片的形式返回给页面,之后前台页面提交到后台进行对比. 1.jar包准备 官方提供的pom应该是 <dependency> <groupId>com.google.code.kaptcha</groupId> <artifactId>kaptcha</arti