Create A Simple Captcha With PHP and GD

Everyone hates captchas. I know I do. It sucks but they are a necessary evil. Most captchas are difficult (sometimes impossible) to read and they will consistantly drive visitors from your site. I’ve been on sites where the captcha was so hard to decipher that I’ve never gone back.

During the development of a new site I was forced to create one of these evil entities. It was surprisingly simple and painless. The captcha that I outline here is very, very simple and should never be used in production without a fair amount of tweaking.

Having developed my site using php I naturally turned to the GD library.

Firstly I generated a random string to display on the captcha :


//generate a random alphanumeric string of a specific length
function gen_random_string($length) 
{
  $characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWZYZ".
        "abcdefghijklmnopqrstuvwxyz";
  $real_string_length = strlen($characters) - 1;
  for($p=0;$p<$length;$p++)
  { $string .= $characters[mt_rand(0, $real_string_length)]; }
  return $string;
}

//add to session array so other scripts can access it for the comparison
$_SESSION['image_text']= gen_random_string(8);

//split into character array - str_split only works in PHP 5
$text_array = str_split($_SESSION['image_text']);


Now that I have my string I need to create the image. Make sure that GD is installed on your php apache server.

//create the image with a background image
$NewImage =imagecreatefrompng("bg1.png");
$cntr = 0;
foreach($text_array as $letter)
{
  //generate a random color for each letter
  $r = rand(0,200);
  $g = rand(0,200);
  $b = rand(0,200);
  $textcolor = imagecolorallocate($NewImage, $r, $g, $b);

  //random horizontal spacing
  $spacing = (rand(5,10)+($cntr*10));
  
  //add the character to the image
  imagestring($NewImage, 5, $spacing, rand(0,10), $letter, $textcolor);
  $cntr++;
}


The code above will generate a GD captcha image with random coloring and random horizontal and vertical spacing on top of a background image.
Now we just need to output it.

//output the headers than the image as a PNG
header('Content-type: image/png');
header('Cache-Control: max-age=0');
header('Expires: '.gmdate('r',time()-3600*24*365));
header('Pragma:');
ImagePNG($NewImage);
imagedestroy($NewImage);


So if I called this file simple-captcha.php I could call it with this html:

<img id='captcha' name='captcha' src="simple-captcha.php">


Here is what it looks like :

This captcha can be strengthened by using other GD image functions such as imagefilledellipse and imageline to create artifacts in the background. It also helps to use different fonts and to change the angle of the letters.

Share

10 Responses to “Create A Simple Captcha With PHP and GD”

  • Steve Says:

    Nice tutorial! That’s a nice looking CAPTCHA. Though, there’s no need to seed with mt_rand since PHP 4.2 since it does it for you. So you can simplify the script by removing that.

  • Cody Taylor Says:

    Thanks for the tip. I’ll update the post accordingly.

  • David Says:

    This is not a very practical Captcha. It would be relatively easy to break since it uses a single font and does not make any effort to distort the letters. reCaptcha is a great project that presents very challenging, yet readable captchas, and in the background users are helping to digitize old books. Check it out: http://recaptcha.net/

  • وبلاگ من و متعه ام Says:

    nice and simple tutorial :)
    thanks.

    suggestion: you can replace “bg1.png” with “bg.php” and generate random background for more seurity.

  • Cody Taylor Says:

    Definitely a good tip.

  • Cody Taylor Says:

    Thanks for the reply. reCaptcha is a neat project. I wonder what books they’re scanning? I also say in the post not to use this for production without tweaking the captcha image quite a bit and I also give some tips on what to change.

  • Austin Says:

    I might be going crazy, but you have:

    function gen_random_string($length)
    {

    }

    and then

    $_SESSION[‘image_text’]=genRandomString(8);

    Your function names don’t match up.

  • Cody Taylor Says:

    Whoops…Not sure how that got by. Thanks for pointing that out. It has now been corrected.

  • Andreas Eriksson Says:

    Nice tutorial. I would rather use a custom captcha than use, for example, reCaptcha.

  • Sandeep Says:

    Hi,
    I am very new to development. I tried the above good stuff and get success in creating the captcha image but did not go further as how to validate the printed letters on image after submitting the form.

    Thanks, please reply.