Anyway, this tutorial will explain how to make your own CAPTCHA like the one below using PHP and the bundled GD image manipulation library. This is the method I use on many projects, and it does the job. Keep in mind that there are stronger CAPTCHA systems available if you want to block the more motivated spammers.
Here's an example: So let's get started. First, we must generated our random code:
Code: Select all
<?php
// start the session to store the variable
session_start();
// generate the random code
$chars = 'abcdefghkmnprstuvwxyzABCDEFGHJKLMNPQRSTUV2345689';
$length = 6;
$code = '';
for($i = 0; $i < $length; $i++){
$pos = mt_rand(0, strlen($chars)-1);
$code .= substr($chars, $pos, 1);
}
// store the code to compare later
$_SESSION['captcha'] = $code;
?>
Note: The mt_rand($min, $max) function generates a random integer, and we will be using it a lot in this script. Specifying the min and max parameters will limit the output to those boundaries.
Now it's time to create the actual image:
Code: Select all
// set up the image
// size
$width = 120;
$height = 30;
// colors
$r = mt_rand(160, 255);
$g = mt_rand(160, 255);
$b = mt_rand(160, 255);
// create handle for new image
$image = imagecreate($width, $height);
// create color handles
$background = imagecolorallocate($image, $r, $g, $b);
$text = imagecolorallocate($image, $r-128, $g-128, $b-128);
// fill the background
imagefill($image, 0, 0, $background);
You can read the comments to figure out what each part does. Basically we created an image, set the dimensions, created the colors with random RGB values, and filled the background. To make sure the background and text aren't the same color, we used the same RGB values minus 128.
We have an image of a solid background, so now it's time to add the code:
Code: Select all
// add characters in random orientation
for($i = 1; $i <= $length; $i++){
$counter = mt_rand(0, 1);
if ($counter == 0){
$angle = mt_rand(0, 30);
}
if ($counter == 1){
$angle = mt_rand(330, 360);
}
// "arial.ttf" can be replaced by any TTF font file stored in the same directory as the script
imagettftext($image, mt_rand(14, 18), $angle, ($i * 18)-8, mt_rand(20, 25), $text, "arial.ttf", substr($code, ($i - 1), 1));
}
Now that we have our code, lets add some effects to help obscure the code:
Code: Select all
// draw a line through the text
imageline($image, 0, mt_rand(5, $height-5), $width, mt_rand(5, $height-5), $text);
// blur the image
$gaussian = array(array(1.0, 2.0, 1.0), array(2.0, 4.0, 2.0), array(1.0, 2.0, 1.0));
imageconvolution($image, $gaussian, 16, 0);
// add a border for looks
imagerectangle($image, 0, 0, $width - 1, $height - 1, $text);
Now that the image is created, it's time to output it to the browser:
Code: Select all
// prevent caching
header('Expires: Tue, 08 Oct 1991 00:00:00 GMT');
header('Cache-Control: no-cache, must-revalidate');
// output the image
header("Content-Type: image/gif");
imagegif($image);
imagedestroy($image);
Here is the complete script:
Code: Select all
<?php
// start the session to store the variable
session_start();
// generate the random code
$chars = 'abcdefghkmnprstuvwxyzABCDEFGHJKLMNPQRSTUV2345689';
$length = 6;
$code = '';
for($i = 0; $i < $length; $i++){
$pos = mt_rand(0, strlen($chars)-1);
$code .= substr($chars, $pos, 1);
}
// store the code to compare later
$_SESSION['captcha'] = $code;
// set up the image
// size
$width = 120;
$height = 30;
// colors
$r = mt_rand(160, 255);
$g = mt_rand(160, 255);
$b = mt_rand(160, 255);
// create handle for new image
$image = imagecreate($width, $height);
// create color handles
$background = imagecolorallocate($image, $r, $g, $b);
$text = imagecolorallocate($image, $r-128, $g-128, $b-128);
// fill the background
imagefill($image, 0, 0, $background);
// add characters in random orientation
for($i = 1; $i <= $length; $i++){
$counter = mt_rand(0, 1);
if ($counter == 0){
$angle = mt_rand(0, 30);
}
if ($counter == 1){
$angle = mt_rand(330, 360);
}
// "arial.ttf" can be replaced by any TTF font file stored in the same directory as the script
imagettftext($image, mt_rand(14, 18), $angle, ($i * 18)-8, mt_rand(20, 25), $text, "arial.ttf", substr($code, ($i - 1), 1));
}
// draw a line through the text
imageline($image, 0, mt_rand(5, $height-5), $width, mt_rand(5, $height-5), $text);
// blur the image
$gaussian = array(array(1.0, 2.0, 1.0), array(2.0, 4.0, 2.0), array(1.0, 2.0, 1.0));
imageconvolution($image, $gaussian, 16, 0);
// add a border for looks
imagerectangle($image, 0, 0, $width - 1, $height - 1, $text);
// prevent caching
header('Expires: Tue, 08 Oct 1991 00:00:00 GMT');
header('Cache-Control: no-cache, must-revalidate');
// output the image
header("Content-Type: image/gif");
imagegif($image);
imagedestroy($image);
?>
Code: Select all
<?php session_start(); ?>
<html>
<head>
<title>CATCHA Test</title>
</head>
<body>
<?php
function valid_captcha($input) {
$code = $_SESSION['captcha'];
unset($_SESSION['captcha']);
return (strcasecmp($input, $code) == 0);
}
if(isset($_POST['captcha'])) {
if(valid_captcha($_POST['captcha'])){
echo '<div>Success</div>';
}
else{
echo '<div>Incorrect</div>';
}
}
?>
<img src="captcha.php" alt="CAPTCHA" width="120" height="30">
<form method="post">
<input type="text" name="captcha" id="captcha">
<input type="submit" name="submit" id="submit" value="Test">
</form>
</body>
</html>
Code: Select all
function valid_captcha($input) {
$code = $_SESSION['captcha'];
unset($_SESSION['captcha']);
return (strcasecmp($input, $code) == 0);
}
That concludes this tutorial. Thanks for reading, and I hope this is useful! You may also be interested in this post on Reloading Images Using JavaScript.
Edit: Fixed a potential exploit in the implementation. The new comparison function destroys the session variable so the same CAPTCHA can't be reused.