How to Make a CAPTCHA with PHP and GD

by Stuart McHenry May 22, 2009

An intro to CAPTCHAs

Captcha is an acronym for Completely Automated Public Turing test to tell Computers and Humans Apart. You’ll likely recognize them as Security Images, a series of random letters or numbers, which you have to enter when sending data on most websites. This verifies that you are a human, and not a robot entering data automatically, such as a spambot.

Captchas aren’t perfect; a spammer can still solve a captcha manually, and software may be created to solve specific captchas to varying degrees of success, but they are still essential for modern websites. They help to dramatically reduce spam and false form entries. Fortunately, it’s relatively easy to make a unique captcha with PHP and GD.

Designing a Captcha

GD is a powerful graphics library for PHP. Good hosting providers will have this library installed by default. To start off we’ll want to create an image based on a background that provides some interference for optical character reading (OCR) software, but not enough to cause difficulty for humans. The following 4 backgrounds will be used in this example:

Secondly, a unique TrueType font (TTF) should be chosen. Although this tutorial will use a simple sans-serif font, feel free to look for something more interesting.

Finally, a character set must be chosen. Some prefer a combination of letter and numbers, or each individually. Either way, characters that resemble others should be avoided.

Once you have these key elements chosen, you’ll want the script to generate and display a random string which will be saved in a session. The displayed string should be altered to make it more difficult for software to recognize the characters.

Putting it Together

With your captcha planned, it’s time to put it into code. The following will begin to create your image from a random PNG background, as well as setup variables such as the font and security string:

ob_start();
session_start();

$im = ImageCreateFromPNG(mt_rand(1, 4).”.png”);

$chars = array(’a’,’b’,’c’,’d’,’e’,’f’,’g’,’h’,’i’,’j’,’k’,’m’,’n’,’p’,’q’,’r’,’t’,’u’,’v’,’w’,’x’,’y’,’z’,’2?,’3?,’4?,’6?,’7?,’8?,’9?);
$str1 = $chars[mt_rand(0, count($chars)-1)];
$str2 = $chars[mt_rand(0, count($chars)-1)];
$str3 = $chars[mt_rand(0, count($chars)-1)];
$str4 = $chars[mt_rand(0, count($chars)-1)];

$font = “font.ttf”;
$size = mt_rand(13, 16);

$_SESSION[‘captcha’] = $str1.$str2.$str3.$str4;

The code below is slightly more complicated, as it outputs the text at a random angle and slightly different positions/colors. You’ll likely want to play with the output parameters.

$angle = mt_rand(-5, 5);
$color = ImageColorAllocate($im, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100));
$textsize = imagettfbbox($size, $angle, $font, $textstr);
$twidth = abs($textsize[2]-$textsize[0]);
$theight = abs($textsize[5]-$textsize[3]);
$x = mt_rand(5, 10);
$y = mt_rand(15,18);
ImageTTFText($im, $size, $angle, $x, $y, $color, $font, $str1);
ImageTTFText($im, $size, $angle, $x+mt_rand(20, 25), $y+mt_rand(1, 3), $color, $font, $str2);
ImageTTFText($im, $size, $angle, $x+mt_rand(45, 50), $y+mt_rand(1, 3), $color, $font, $str3);
ImageTTFText($im, $size, $angle, $x+mt_rand(65, 70), $y+mt_rand(1, 3), $color, $font, $str4);

Finally, we’ll have the following code output our finalized image.

header(“Content-Type: image/png”);
ImagePNG($im);
ob_end_flush();
imagedestroy($im);

Integrating The Final Product

The code above should output something like the following (refresh to see another):

The text in the captcha is stored in a PHP session. This can be accessed in your scripts using the global variable $_SESSION[‘captcha’]. Be sure to call session_start(); at the start of your script first.

Further Considerations/References

To strengthen your captcha further, look into some of the many functions GD has: GD Reference. A great place to find many free fonts is UrbanFonts.com or DaFont.com

Feel free to use the code above as you see fit. It has been released as GPL v2 as part of an open source project that I worked on. The background images are also free to use, however, I would recommend creating your own.

Stuart McHenry
Stuart McHenry is a US-based SEO Consultant focusing on link building, content marketing, local SEO, and reputation management. Follow Stuart on Twitter @smindsrt

Leave a Reply