본문 바로가기
프로그래밍/PHP

게시판 자동 글등록 막기

by 백룡화검 2010. 4. 23.
##########0*

머 새로운 기법은 아니구요..
기본으로 확인코드에 사용되는 코드는 노출되어 있습니다만,

확인에 사용되는 코드를 만드는 로직을 보시고
자신의 입맛에 맞게 조금씩만 수정하시면 자신만의 암호화가 되니깐
별문제 없다고 보여지네요..
행여나 자동글이 등록이 되면 코드 한번 손봐주면 됩니다.

거기에 gd 를 이용하여 이미지로 생성됩니다.
행여나 이미지판독에 대응하여 픽셀화를 무력시켜보고자
격자무늬도 넣었구 랜덤으로 점두 찍어놨습니다.

머 이것 해석할정도의 이미지판독프로그램이라면
생성된 이미지를 한두조각 나눠서 배치를 해주시면 될듯합니다.

write.html-------------------------------
<?
$key = time();
?>
<form>
<input type=hidden name=time_key value=<?echo $key;?>> //기준코드
<img src=write_code.php?time_key=<?echo $key;?>> //이미지생성
<input type=text name=input_key> //확인코드 입력받는곳
<input type=submit>
</form>


write_code.php----------------------------------
// 이해가 쉽게 함수를 여기에 넣어놨는데
// 함수부분만 따로 파일로 만들어서 include 시켜서 하세요..
// 테스트용으로 한파일에서 결과 보기 편하게 같이 넣었습니다.

<?
// 함수 설명
// 타임스템프 자리는 10자리다
// 5자리씩 끊어서 배열에 넣는다. 비교할 두 수를 만들기 위해서
// 너무 큰값을 방지하고자 중복배열 제거한다.
// 타임프템프 맨 마지막 10번째 자리만 초단위로 변하고 나머진 정적이다.
// 고로 고정값을 피하기 위해서
// 중복 제거된 배열의 합 곱하기 맨 마지막 초단위 수
// 맨마지막 수가 0이면 임의의 수를 준다. 123 곱하기 0 은 0 이니까
function write_code($time_key){
    // 두분류로 나눈다.
                // 여기 코드는 공개되어있기때문에 자기 입맛에 따라서......
    $time[0] = substr($time_key, 0, 5); // 여기 자리수도 임의로 쪼갤것
    $time[1] = substr($time_key, 5, 9); // 여기도 위에 자리수에 맞춰서..
    //마지막 숫자가 0일경우 에러 난다 123 곱하기 0  = 0이다.
    if(substr($time_key, 9, 1) == 0){$last_key = 5;}// 임의로 넣을것!
    else{$last_key = substr($time_key, 9, 1);}
    
    //각 배열에 넣는다.
    for($i=0 ; $i <= 1 ; $i++){
        for($sub_i=0 ; $sub_i <= 4 ; $sub_i++){
            $array_time[$i][$sub_i] = substr($time[$i], $sub_i,1);
        }
        //각 배열의 중복 제거
        $array_time[$i] = array_unique($array_time[$i]); // 큰값 원하면 안해두 된다
        //각 배열의 합 * $time_key 의 마지막 값
        $array_time[$i] = array_sum($array_time[$i]) * $last_key;
    }
    $array_time[2] = max($array_time[0],$array_time[1]);
    $array_time[3] = min($array_time[0],$array_time[1]);
    // 맨 마지막 수 홀수 ,짝수로 큰수를 구할지 작은수를 구할지 결정
    if($last_key % 2 == 1){ //홀수라면
        $array_time[4] = 1; // 작은값을 구해라 옵션
        $array_time[5] = "작은값을 구하시오"; //한글텍스트문장
        $array_time[6] = $array_time[3]; //정답
    }
    else{
        $array_time[4] = 2; // 큰값을 구해라 옵션
        $array_time[5] = "큰값을 구하시오"; //한글텍스트문장
        $array_time[6] = $array_time[2]; //정갑
    }
    return $array_time;
}

header("Content-type:image/png");

    $width= "600";
    $height="60";
        $im = imagecreate($width,$height);

        $white = imagecolorallocate($im,255,255,255);
        $black = imagecolorallocate($im,0,0,0);

        // 원그리기 시작위치y 시작위치x 크기 x 크기 y
        for($i=15;$i<=585;$i+=rand(20,35)){ // 가로 시작점
        $f = rand(10,50);    // 세로 시작점
        $b = rand(3,5);        // 원의 크기
        ImageArc ($im, $i, $f, $b, $b, 0, 360, $black); // 원 그리기
        ImageFill ($im, $i, $f, $black); //그린원에 색채우기
    }
            // 격자 무늬 넣기
    $num = rand(0,5);
        for ($i=$num; $i<=$width; $i+=rand(15,20)){  // 가로 선
            imageline($im,$i,0,$i,$height,$black);
        }

        for ($i=$num; $i<=$height+10; $i+=rand(10,15)){ //세로 선
            imageline($im,0,$i,$width,$i,$black);
    }
    $write_code = write_code($_GET[time_key]);
                // 문자 만들기
    $code_text = "($write_code[0])($write_code[1]) 두 수의 $write_code[5]";
    imagettftext($im, 24, 0, 25, 37, $black, 'batang.ttc', iconv("EUC-KR","UTF-8",$code_text));
        imagepng($im);
        imagedestroy($im);
       
?>

마지막으로 글등록 페이지에서

// 위에 페이지에서 함수를 같이 써놨는데
// 실제로는 따로 빼놓는것이 좋습니다.
include "make_code.php"; // 위에 키 만드는 함수가 들어있는파일

$write_code = write_code($_POST[time_key]);

if($write_code[6] != $_POST[input_key]){
    echo"자동등록방지 코드가 틀립니다.";exit
}

이상입니다. 머.. 정리도 잘 안되고 좀 그렇긴 한데...
write_code.php 이파일에
time_key 만 임의로 줘서 바로 결과를 보실수 있습니다.

ps : 폰트 파일은 윈도우 폰트에 'batang.ttc'를 가져다 써봤습니다.
제가 유니코드 지원하는 폰트가 없어서 찾다가 포기하구 윈도폰트로 했어요..

로직 부분은 대충 이해를 하시고 그런형식으로 만드시구..
정작 초보님들이 필요로 하시는건
격자에 점찍고 그위에 결과 텍스트 입력하는 부분일거 같군요..
그럼 20000~~

 

출처 : PHPSCHOOL