본문 바로가기

Java

captcha를 만들어보자

captcha를 공부해보려고 여기저기 기웃거리다가 simple captcha로 한번 테스트 페이지를 만들어보려고 작업했다. 근데 문제가 텍스트는 아주 잘되는데 오디오는 방법을 잘 모르겠다. 그래서 좀 더 여기저기 기웃거리다 텍스트로된 것을 직접 만든 소스를 발견했다. 소스를 보니 생각보다 간단하게 작성이 됬다. 그래서 가져와서 조금 수정해보았다.


출처: http://zetcode.com/tutorials/jeetutorials/captcha/


import java.awt.Color;

import java.awt.Font;

import java.awt.GradientPaint;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.image.BufferedImage;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Random;


import javax.imageio.ImageIO;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


public class Captcha {

public static void makeTextImage(HttpServletRequest request, 

HttpServletResponse response) 

throws ServletException, IOException {

int width = 150;

int height = 50;

BufferedImage bufferedImage = new BufferedImage(width, height, 

BufferedImage.TYPE_INT_RGB);

Graphics2D g2d = bufferedImage.createGraphics();

Font font = new Font("Georgia", Font.BOLD, 18);

g2d.setFont(font);

RenderingHints rh = new RenderingHints(

RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

rh.put(RenderingHints.KEY_RENDERING, 

RenderingHints.VALUE_RENDER_QUALITY);

g2d.setRenderingHints(rh);

GradientPaint gp = new GradientPaint(0, 0, 

Color.green, 0, height/2, Color.black, true);

g2d.setPaint(gp);

g2d.fillRect(0, 0, width, height);

g2d.setColor(new Color(255, 153, 0));

char[] data = generateKeyRandomText();

String captcha = String.copyValueOf(data);

request.getSession().setAttribute("captcha", captcha );

int x = 0; 

int y = 0;

Random r = new Random();

for (int i=0; i<data.length; i++) {

x += 10 + (Math.abs(r.nextInt()) % 15);

y = 20 + Math.abs(r.nextInt()) % 20;

g2d.drawChars(data, i, 1, x, y);

}

g2d.dispose();

response.setContentType("image/png");

OutputStream os = response.getOutputStream();

ImageIO.write(bufferedImage, "png", os);

os.close();

}

private static char[] generateKeyText(){

char data[][] = {

{ 'z', 'e', 't', 'c', 'o', 'd', 'e' },

{ 'l', 'i', 'n', 'u', 'x' },

{ 'f', 'r', 'e', 'e', 'b', 's', 'd' },

{ 'u', 'b', 'u', 'n', 't', 'u' },

{ 'j', 'e', 'e' }

};

Random r = new Random();

int index = Math.abs(r.nextInt()) % 5;

return data[index];

}

private static char[] generateKeyRandomText(){

char data[] = {0, 0, 0, 0, 0, 0};

char alphaCnt = ('Z'-'A'+1);

char numCnt = ('9'-'0'+1);

char totalCnt =  (char)((alphaCnt * 2) + numCnt);

char zero = '0';

char lowerA = 'a';

char upperA = 'A';

Random r = new Random();

for(int i=0; i<data.length; i++){

int index = Math.abs(r.nextInt()) % totalCnt;

if(index < numCnt){

data[i] = (char) (zero + index);

}else if(index < (numCnt + alphaCnt)){

data[i] = (char)  (upperA + index - numCnt);

}else{

data[i] = (char) (lowerA + index - numCnt - alphaCnt);

}

}

return data;

}

}



클래스를 따로 만들어보았다. 미리 저장된 문자열을 사용하게 되어 있었는데, 6자리 문자열을 랜덤하게 만들도록 수정했다. generateKeyText메서드가 원본, generateKeyRandomText 메서드가 수정본이다. 사용하는 것은 간단하다. 다음은 이미지 생성 코드이다.

@RequestMapping("/capchaTest")

protected void capchaTest(HttpServletRequest request, 

HttpServletResponse response)

            throws ServletException, IOException {

Captcha.makeTextImage(request, response);

}


확인은 다음 코드로 하면 된다.

String captcha = (String) session.getAttribute("captcha");

String code = (String) request.getParameter("code");


if (captcha != null && code != null) {

if (captcha.equals(code)) {

out.print("<p class='alert'>Correct</p>");

} else {

out.print("<p class='alert'>Incorrect</p>");

}

}


이건 어디서 많이 봤다 싶었는데, simple chaptcha의 예제와 동일하다. 중간에 폼으로 넘기는 부분은 생략하겠다. 출처 사이트에 보면 자세히 나와있으니 출처 사이트도 보기를 권한다.