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>
 
原文地址:https://www.cnblogs.com/hui1107464497/p/4502020.html