Home > PHP, Tutorials > Captcha

Captcha

I've kinda written a CAPTCHA image file :) Code after the jump.
Code explanation is right behind it; (Please view full).

 
<?php
session_start();
$numlines = 4;		// 4 lines/rectangles
$numcrap = 15;		// 15 bullcrap letters behind it.
$str = md5(microtime());
$crap = base64_encode(md5(sha1(microtime())));
$str = substr($str,0,5);
// Str = the string shown in the captcha
$_SESSION['captcha'] = $str;

Up until here, we've just initialized some variables. They kinda speak for themselves. $crap is merely some random nonsense to be displayed behind the actual text. Also, we've already registered the captcha string in the SESSION.

 
$img =imagecreate(200,50);
imagecolorallocate($img, 200,200,200);
$text = imagecolorallocate($img, 255, 0, 255);

One guess what happened here. We've created an image. We've set the background color to RGB(200,200,200) with the first imagecolorallocate. We've also defined the text color: Magenta.

 
for ($i=0;$i<$numlines;$i++)
{
	if ($i%2)
		imagerectangle($img, rand(0,50),rand(0,50),rand(100,200),rand(0,50),imagecolorallocate($img,170,170,170));
	else
		imageline($img, rand(0,50),rand(0,50),rand(100,200),rand(0,50),imagecolorallocate($img,170,170,170));
}
//Draw crap letters behind the true ones.
for ($i = 0; $i < $numcrap; $i++)
	imagettftext($img, rand(18,25), rand(-30,30), (200/$numcrap)*$i, rand(20,50), imagecolorallocate($img,180,180,180), "lucon.ttf", $crap{$i});

Woot, we've drawn some crap. A lot of rectangles and lines, and the $crap contents.

 
for ($i = 0; $i < 5; $i++)
	imagettftext($img, rand(18,25), rand(-30,30), rand(($i*30)-10,($i*30)+10), rand(20,50), $text, "lucon.ttf", $str{$i});

this code is virtually the same as above, only now I'll explain how it works. Firstly, the imagettftext() function accepts these variables:

 
imagettftext  ( resource $image  , float $size  , float $angle  , int $x  , int $y  , int $color  , string $fontfile  , string $text  )

So we've passed the $image handle, give it a random size between 18 and 25 pixels, make it tilt up to 30 degrees either way. Then there's some complicated math ( rand(($i*30)-10,($i*30)+10) ), which basically allows every letter to still be visible and printed, in the right order. We place it on a random height between 20 and 50 pixels from the top.
we pass the Lucida Console font handle to it, and lastly we send in the actual text that needs to be printed $STRING{NUMBER} returns the NUMBERth letter from the STRING.

 
header("Content-Type: image/jpeg");
imagejpeg($img);
?>

And lastly we're outputting the image, and telling the browser it's an image file:

See here, the captcha in action:

I've added the black letters so you can see what it's supposed to read ;)

PHP, Tutorials

  1. May 24th, 2008 at 08:57 | #1

    Aighttt, looks awesome! :)

  1. No trackbacks yet.