VerifyCodeUtils生成验证码工具类

package com.cdms.common.utils;

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.IOException;

import java.io.OutputStream;

import java.security.SecureRandom;

import java.util.Arrays;

import java.util.Random;

import javax.imageio.ImageIO;

/**

* 验证码工具类

*

* @author yanwg

*/

public class VerifyCodeUtils

{

// 使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符

    public static final StringVERIFY_CODES ="123456789ABCDEFGHJKLMNPQRSTUVWXYZ";

    private static Randomrandom =new SecureRandom();

    /**

    * 使用系统默认字符源生成验证码

    *

    * @param verifySize 验证码长度

    * @return

    */

    public static StringgenerateVerifyCode(int verifySize)

{

return generateVerifyCode(verifySize, VERIFY_CODES);

    }

/**

    * 使用指定源生成验证码

    *

    * @param verifySize 验证码长度

    * @param sources 验证码字符源

    * @return

    */

    public static StringgenerateVerifyCode(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 os

    * @param code

    * @throws IOException

*/

    public static void outputImage(int w, int h, OutputStream os, String code)throws IOException

{

int verifySize = code.length();

        BufferedImage image =new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

        Random rand =new Random();

        Graphics2D g2 = image.createGraphics();

        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        Color[] colors =new Color[5];

        Color[] colorSpaces =new Color[] { Color.WHITE, Color.CYAN, Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA,

                Color.ORANGE, Color.PINK, Color.YELLOW };

        float[] fractions =new float[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 =new Random();

        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 =new Font("Algerian", Font.ITALIC, fontSize);

        g2.setFont(font);

        char[] chars = code.toCharArray();

        for (int i =0; i < verifySize; i++)

{

AffineTransform affine =new AffineTransform();

            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);

    }

private static ColorgetRandColor(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);

        return new Color(r, g, b);

    }

private static int getRandomIntColor()

{

int[] rgb =getRandomRgb();

        int color =0;

        for (int c : rgb)

{

color = color <<8;

            color = color | c;

        }

return color;

    }

private static int[]getRandomRgb()

{

int[] rgb =new int[3];

        for (int i =0; i <3; i++)

{

rgb[i] =random.nextInt(255);

        }

return rgb;

    }

private static void shear(Graphics g, int w1, int h1, Color color)

{

shearX(g, w1, h1, color);

        shearY(g, w1, h1, color);

    }

private static void 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);

            }

}

}

private static void 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);

            }

}

}

}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • vcode.jsp <%@page import="com.yc.res.util.VerifyCodeUtils...
    Arance阅读 618评论 0 0
  • http://blog.csdn.net/ayhlay/article/details/13625275 1.验证...
    蘋果_283e阅读 460评论 0 0
  • java验证码的主要思路 1.生成一个固定尾数的随机字符串 2.在内存中创建一个图片(固定高度和宽度的矩形) ...
    heen11阅读 1,278评论 0 1
  • 验证码增加了应用的安全性,验证码也有各种各样,如数字字母组合、汉字、点击数字等,其本质就是后台生成的验证码与前端输...
    楠小六阅读 482评论 0 0
  • 新建JSP文件 如code.jsp 复制如下代码 <%@ page language="java" content...
    矫矫矫阅读 346评论 0 0