You are here: Home » Tutorials » Web Development » PHP » Image Manipulation » Creating a CAPTCHA image with security code to validate forms..

Creating a CAPTCHA image with security code to validate forms

Added February 25, 2008, read 1758 times

In this tutorial you will learn to create a security code image generator, or a CAPTCHA image, that is so helpfull against spammers.

Let's get going. First, here is the full code, just in case you understand it on your own:

The php code that generates the image and the security code:

PHP Code
<?php
session_start();

$w = 120; // height of the image
$h = 40; // width of the image
$l = 5; // length of security code
$baseList = '0123456789abcdfghjkmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; // the characters to be used when generating the code

$code = "";
$counter = 0;

$img = @imagecreate($w, $h) or die('Cannot initialize GD!'); // create image

for ($i = 0; $i < 10; $i++)
{
	imageline($img, mt_rand(0, $w), mt_rand(0, $h), mt_rand(0, $w), mt_rand(0, $h),
		imagecolorallocate($img, mt_rand(150, 255), mt_rand(150, 255), mt_rand(150, 255)));
}

for ($i = 0, $x = 0; $i < $l; $i++)
{
	$randChar = substr($baseList, rand(0, strlen($baseList) - 1), 1);
	$x += 10 + mt_rand(0, 10);
	imagechar($img, mt_rand(3, 5), $x, mt_rand(5, 20), $randChar, imagecolorallocate
		($img, mt_rand(0, 155), mt_rand(0, 155), mt_rand(0, 155)));
	$code .= strtolower($randChar);
}

header('Content-Type: image/jpeg');
imagejpeg($img);
imagedestroy($img);

$_SESSION['secCode'] = $code;

?>
Select all

And the html form to test the script:

HTML Code
<?php session_start(); ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "DTD/xhtml1-transitional.dtd">
<html>
<head>
   <title>Captcha demo</title>
</head>
<body>

<?php
if (isset($_POST['submitBtn']))
{
	$secCode = isset($_POST['secCode']) ? strtolower($_POST['secCode']) : "";
	if ($secCode == $_SESSION['secCode'])
	{
		echo "<p>The result code was valid!<br/></p>";
		unset($_SESSION['secCode']);
		$result = true;
	}
	else
	{
		echo "<p>Sorry the security code is invalid! Please try it again!</p>";
		$result = false;
	}
}
else
{
?>      
      <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" >
        <table width="400">
          <tr>
            <td>Security code: 
               <input name="secCode" type="text" size="10" />
            </td>
            <td>
               <img src="securityCode.php" alt="captcha security code" />
            </td>
          </tr>
          <tr>
            <td colspan="2"><br/>
               <input type="submit" name="submitBtn" value="Send" />
            </td>
          </tr>
        </table>  
      </form>
<?php
}
?>      
</body>
Select all

Now for some explanation. To create the image we need the width and height of the output image. We use these variables:

PHP Code
$w = 120; // height of the image
$h = 40; // width of the image
$l = 5; // length of security code
$baseList = '0123456789abcdfghjkmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; // the characters to be used when generating the code
Select all

The additional variables are to be used when generating the random code/string that will later be displayed in the foreground of the image. The background needs to make the reading of the code a little difficult, so we generate a number of random lines using the mt_rand() function. We do this using the imageline() function, sending the coordonates of the starting and ending point of the lines. Also, the color of the lines is picked randomly using imagecolorallocate() function. In this example we use 10 lines::

PHP Code
$img = @imagecreate($w, $h) or die('Cannot initialize GD!'); // create image

for ($i = 0; $i < 10; $i++)
{
	imageline($img, mt_rand(0, $w), mt_rand(0, $h), mt_rand(0, $w), mt_rand(0, $h),
		imagecolorallocate($img, mt_rand(150, 255), mt_rand(150, 255), mt_rand(150, 255)));
}
Select all

After we created the image, generated the lines on the background, we move on to generating the random security from the list of chars defined by $baseList.

PHP Code
for ($i = 0, $x = 0; $i < $l; $i++)
{
	$randChar = substr($baseList, rand(0, strlen($baseList) - 1), 1);
	$x += 10 + mt_rand(0, 10);
	imagechar($img, mt_rand(3, 5), $x, mt_rand(5, 20), $randChar, imagecolorallocate
		($img, mt_rand(0, 155), mt_rand(0, 155), mt_rand(0, 155)));
	$code .= strtolower($randChar);
}
Select all

Using the length of the code we print each character one by one on the background of the image using the imagechar() function and assigning a random color to each character. strtolower() makes all characters lower case, so we make the security code case-sensitive.

Because will will use this script as the source of the image, we must send the appropiate header:

PHP Code
header('Content-Type: image/jpeg');
imagejpeg($img);
imagedestroy($img);

$_SESSION['secCode'] = $code; // assign the code to a session variable
Select all

We use the $_SESSION['secCode'] variable to store the generated code and keep it after the form has been submitted, in order to verify the entered code.

PHP Code
$secCode = isset($_POST['secCode']) ? strtolower($_POST['secCode']) : "";
if ($secCode == $_SESSION['secCode'])
{
	echo "<p>The result code was valid!<br/></p>";
	unset($_SESSION['secCode']);
	$result = true;
}
else
{
	echo "<p>Sorry the security code is invalid! Please try it again!</p>";
	$result = false;
}
Select all

The above code validats the input code against the session stored code, returns true if successful match, and false otherwise.

The HTML code provides a demo form for testing the script, you can integrate it in any form of your choice. Good luck!

Discuss

  • Your name
  • Your email (we'll keep this to ourselves)
  • What's it about?
  • Security check

Security check

Type in the field on the left the code displayed on the image below.

Comments:

Awesum Code

posted by Girish Singh on March 10, 2008 at 2:48 PM

Awesum and really easy to understand.. Worked like a charm.

However I would suggest that you can please put up all the code in one zip file , that would make it really easier to put up and try

Another thing which I found after looking a lot for it on the net was the asp.net way of captcha. Although not very popular I say, one of my clients needed it.

Good Code

posted by Sinisa Vukovic on March 13, 2008 at 3:25 PM

I like this code very much,it's easy to understand.

THANK YOU VERY MUCH!!!