1. 程式人生 > >java實現圖片隨機驗證碼

java實現圖片隨機驗證碼

轉自:https://blog.csdn.net/zhulin40/article/details/51899487
<div class="form-group  col-lg-6">  
    <label for="id" class="col-sm-4 control-label">  
        驗證碼:  
    </label>  
    <div class="col-sm-8">  
        <input type="text" id="code" name="code" class="form-control" style="width:250px;"/>  
        <img id="imgObj" alt="驗證碼" src="/article/validateCode" onclick="changeImg()"/>  
        <a href="#" onclick="changeImg()">換一張</a>  
    </div>  
</div>  
  
<script type="text/javascript">  
    // 重新整理圖片  
    function changeImg() {  
        var imgSrc = $("#imgObj");  
        var src = imgSrc.attr("src");  
        imgSrc.attr("src", changeUrl(src));  
    }  
    //為了使每次生成圖片不一致,即不讓瀏覽器讀快取,所以需要加上時間戳  
    function changeUrl(url) {  
        var timestamp = (new Date()).valueOf();  
        var index = url.indexOf("?",url);  
        if (index > 0) {  
            url = url.substring(0, url.indexOf(url, "?"));  
        }  
        if ((url.indexOf("&") >= 0)) {  
            url = url + "×tamp=" + timestamp;  
        } else {  
            url = url + "?timestamp=" + timestamp;  
        }  
        return url;  
    }  
</script>

package cc.zenking.cloud.zksc.sso.util;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.Random;

/**
 * 驗證碼生成器
 * 
 * @author
 */
public class VerificationCodeImgUtil {
	// 圖片的寬度。
	private int width = 160;
	// 圖片的高度。
	private int height = 40;
	// 驗證碼字元個數
	private int codeCount = 5;
	// 驗證碼干擾線數
	private int lineCount = 150;
	// 驗證碼
	private String code = null;
	// 驗證碼圖片Buffer
	private BufferedImage buffImg = null;

	// 驗證碼範圍,去掉0(數字)和O(拼音)容易混淆的(小寫的1和L也可以去掉,大寫不用了)
	private char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R',
			'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

	/**
	 * 預設建構函式,設定預設引數
	 */
	public VerificationCodeImgUtil() {
		this.createCode();
	}

	/**
	 * @param width
	 *            圖片寬
	 * @param height
	 *            圖片高
	 */
	public VerificationCodeImgUtil(int width, int height) {
		this.width = width;
		this.height = height;
		this.createCode();
	}

	/**
	 * @param width
	 *            圖片寬
	 * @param height
	 *            圖片高
	 * @param codeCount
	 *            字元個數
	 * @param lineCount
	 *            干擾線條數
	 */
	public VerificationCodeImgUtil(int width, int height, int codeCount, int lineCount) {
		this.width = width;
		this.height = height;
		this.codeCount = codeCount;
		this.lineCount = lineCount;
		this.createCode();
	}

	public void createCode() {
		int x = 0, fontHeight = 0, codeY = 0;
		int red = 0, green = 0, blue = 0;

		x = width / (codeCount + 2);// 每個字元的寬度(左右各空出一個字元)
		fontHeight = height - 2;// 字型的高度
		codeY = height - 4;

		// 影象buffer
		buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics2D g = buffImg.createGraphics();
		// 生成隨機數
		Random random = new Random();
		// 將影象填充為白色
		g.setColor(Color.WHITE);
		g.fillRect(0, 0, width, height);
		// 建立字型,可以修改為其它的
		Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);
		// Font font = new Font("Times New Roman", Font.ROMAN_BASELINE, fontHeight);
		g.setFont(font);

		for (int i = 0; i < lineCount; i++) {
			// 設定隨機開始和結束座標
			int xs = random.nextInt(width);// x座標開始
			int ys = random.nextInt(height);// y座標開始
			int xe = xs + random.nextInt(width / 8);// x座標結束
			int ye = ys + random.nextInt(height / 8);// y座標結束

			// 產生隨機的顏色值,讓輸出的每個干擾線的顏色值都將不同。
			red = random.nextInt(255);
			green = random.nextInt(255);
			blue = random.nextInt(255);
			g.setColor(new Color(red, green, blue));
			g.drawLine(xs, ys, xe, ye);
		}

		// randomCode記錄隨機產生的驗證碼
		StringBuffer randomCode = new StringBuffer();
		// 隨機產生codeCount個字元的驗證碼。
		for (int i = 0; i < codeCount; i++) {
			String strRand = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);
			// 產生隨機的顏色值,讓輸出的每個字元的顏色值都將不同。
			red = random.nextInt(255);
			green = random.nextInt(255);
			blue = random.nextInt(255);
			g.setColor(new Color(red, green, blue));
			g.drawString(strRand, (i + 1) * x, codeY);
			// 將產生的四個隨機數組合在一起。
			randomCode.append(strRand);
		}
		// 將四位數字的驗證碼儲存到Session中。
		code = randomCode.toString();
	}

	public void write(String path) throws IOException {
		OutputStream sos = new FileOutputStream(path);
		this.write(sos);
	}

	public void write(OutputStream sos) throws IOException {
		ImageIO.write(buffImg, "png", sos);
		sos.close();
	}

	public BufferedImage getBuffImg() {
		return buffImg;
	}

	public String getCode() {
		return code;
	}

	/**
	 * 測試函式,預設生成到d盤
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		VerificationCodeImgUtil vCode = new VerificationCodeImgUtil(160, 40, 5, 150);
		try {
			String path = "D:/" + new Date().getTime() + ".png";
			System.out.println(vCode.getCode() + " >" + path);
			vCode.write(path);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 /** 
    * @Title: validateCode 
    * @Description: (響應驗證碼頁面 ) 
    * @param @param request
    * @param @param response
    * @param @return
    * @param @throws Exception    設定檔案 
    * @return String    返回型別 
    * @throws 
    */
    @RequestMapping(value="/validateCode")  
    public String validateCode(HttpServletRequest request,HttpServletResponse response) throws Exception{  
        // 設定響應的型別格式為圖片格式  
        response.setContentType("image/jpeg");  
        //禁止影象快取。  
        response.setHeader("Pragma", "no-cache");  
        response.setHeader("Cache-Control", "no-cache");  
        response.setDateHeader("Expires", 0);  
      
        HttpSession session = request.getSession();  
      
        VerificationCodeImgUtil vCode = new VerificationCodeImgUtil(120,40,5,100);  
        session.setAttribute("code", vCode.getCode());  
        vCode.write(response.getOutputStream());  
        return null;  
    } 

   /**
     * 登入
     *
     * @return
     */
    @RequestMapping(value = "/login")
    public ResponseEntity<Object> login(HttpServletRequest request,LoginRequest loginRequest) {
    	String code = request.getParameter("code");  
    	HttpSession session = request.getSession();  
    	String sessionCode = (String) session.getAttribute("code");  
    	if (!StringUtils.equalsIgnoreCase(code, sessionCode)) {  //忽略驗證碼大小寫  
//    	    throw new RuntimeException("驗證碼對應不上code=" + code + "  sessionCode=" + sessionCode); 
    	    return JsonResponse.fail(ErrorCode.ERROR_CODE_1017);
    	} 
        int n = userService.Login(loginRequest);
        if (n > 0) {
            return JsonResponse.success(n);
        }
        return JsonResponse.fail(ErrorCode.ERROR_CODE_1012);
    }