PHP Simple CAPTCHA Example

Thursday, February 12, 2009

CAPTCHA stands for Completely Automated Public Turing Test to tell Computers and Humans Apart. It is mainly used to stop computer programs from submitting form on a web page automatically, sending automated email, and other tasks. Although the term can refer to a wide variety of methods like autio bites, riddles, etc, the typical method used by many applications is interpretation of a graphic, a graphic that contains text in it that has been altered/distorted/obscured in ways that should make it difficult for OCR proframs to actually try to parse the data out of the graphic, yet, uhman can still read it.

Many different types of distortions can be done like bending the text, rotating it, putting dots, lines, and so on. Here's an example of PHP with GD library to generate CAPTCHA graphic.

<?php
$w = 300;
$h = 50;
$gfx = imagecreatetruecolor($w, $h);

imageantialias($gfx, true);

$white = imagecolorallocate($gfx, 255, 255, 255);
imagefilledrectangle($gfx, 0, 0, $w-1, $h-1, $white);

$str = '';
foreach (range(0, rand(5,7)) as $r) {
    $str .= chr(rand(65,90));
}

$pos = $w / strlen($str);

foreach(range(0, strlen($str) - 1) as $s) {
    $shade = rand(0, 100);
    $tmpgray = imagecolorallocate($gfx, $shade, $shade, $shade);
    imagettftext($gfx,     
        rand($h/3, $h/2), 
        rand(-60, 60),     
        $s*$pos+($pos*.4), 
        rand($h*.5,$h*.7), 
        $tmpgray,         
        'arial',           
        $str{$s});         
}

foreach(range(-$h, $w, 5) as $x) {
    $shade = rand(50,254);
    $tmpgray = imagecolorallocate($gfx, $shade, $shade, $shade);
    imageline($gfx, $x, 0, $x+$h+rand(0,25), $h-1, $tmpgray);
    imageline($gfx, $x, $h-1, $x+$h+rand(0,25), 0, $tmpgray);
}

session_start();
$_SESSION['captcha'] = $str;
header('Content-type: image/png');
imagepng($gfx);
?>


Save the script as captcha.php. And here's the example of how to use it on a web page
<?php
session_start();
if (count($_POST)) {
   if (isset($_SESSION['captcha'])) {
        if ($_SESSION['captcha'] === strtoupper($_POST['check'])) {
            //on success
     unset($_SESSION['captcha']);
            echo "Congratulations, you typed it in correctly!";
        } else {
            //on failed
            echo "Sorry, that wasn't it, try again!";
        }
    } else {
   //on same session
        echo "Sorry, no spamming aloud!";
    }
}
?>
<form action="<?= $_SERVER['PHP_SELF'] ?>" method="post">
Please enter the text that you see in the following graphic:<br />
<img src="captcha.php" /><br />
<input name="check" type="text"><br />
<input name="Submit" type="submit">
</form>


Remember, after you have validated a user, you MUST destroy the session variable that held the CAPTCHA key. If you don't do this, it is possible for a user to submit the same form many times through a variation on session hijacking, providing the same session id and the same text that matches the key. Because the key wasn't destroyed, this will work and will continue to work until that session expires. Therefore, always destroy the key as soon as possible.

Hope it helps.

0 comments: