If you are un-aware of what CAPTCHA is, please refer to this.
Click for an example!
This is a tutorial on how to make your own CAPTCHA image, and how to use it! Let's begin!
First open up a PHP file, save it to your server and call in
captcha.php
We will be using a session variable to store our CAPTCHA code in for later use, so we need to make sure we can use sessions.
PHP Code:
session_start();
We're gonna store this code inside a function, though for this particular example, you don't need to, it is optional, but as I say, I will be storing it inside a function.
The function will be called
captcha
PHP Code:
function captcha($length = 6) { // Start of function
The
$length variable is defaulted to
6, though this can be any number you wish, though I recommend you keep it between 4 and 6.
Tip: if your going to use this with different forms and specify different lengths for each one, then do not specify a length, just keep it as $length
When using the CAPTCHA code, you can specify a length by adding a
GET method to your URL to specify how many characters you want your CAPTCHA code to be, but we'll come back to that at the end of this tutorial. We need to check if one is set, otherwise it will be set to it's default number.
PHP Code:
$length = isset($_GET['chars']) ? $_GET['chars'] : 6;
Now we need to generate a random string, which will be our random CAPTCHA code. I will do this my getting a complete random number between
0 and
999 and then encrypting it, this will be referred to as the
hash.
PHP Code:
$hash = md5(rand(0, 999));
Now I know what your thinking, when you encrypt a string, it turns it into a 32 character string, well indeed it does, which is why we trim it down to the length we specified earlier in our
$length variable.
PHP Code:
$code = substr($hash, 15, $length);
What this does is takes the random generated hash, starts at the 15th character and trims it down to
$length, which in this case, is 6.
Now that we have our random code, we need to store it in a session, which is simple enough.
PHP Code:
$_SESSION["captcha"] = $code;
Self explanatory I would think.
Okay! Now onto creating the image.
Warning: you must have GD installed on your server.
We need to create the image size, so let's set a width and a height... this can be to any size you wish, but I recommend keeping it at around the size specified in this tutorial, it is a good size.
PHP Code:
$width = 200;
$height = 50;
Now we create our image using the set variables above.
PHP Code:
$image = imagecreate($width, $height);
Now just because we can, lets make the image colourful. We'll assign some random RGB (red, green, blue) colours so that on each load, it'll most likely be a different colour. We're not using HEX colours in this, as the function we're using doesn't support it (or at least not that I know of) and to make a colour using RGB, you need to set three numbers between 0 and 255 to get the colour you want. Because we need three numbers, we assign three variables with the same value, because if we set just one variable with the same value, it will always be the same colour.
PHP Code:
$rgb1 = rand(0, 255);
$rgb2 = rand(0, 255);
$rgb3 = rand(0, 255);
Still with me? Good...
Now we need to colour in our image we made earlier, we do this like so:
PHP Code:
$background = imagecolorallocate($image, $rgb1, $rgb2, $rgb3);
This will make our image a different colour on each reload. Now let's do the same for the text, which is the CAPTCHA code. The only different here is that with the given random number generated, we minus 50 and it gives it more of a transparent look, which trust me, looks good. This is of course optional.
PHP Code:
$text = imagecolorallocate($image, ($rgb1 - 50), ($rgb2 - 50), ($rgb3 - 50));
Now we have our set variables, we create the final image with our background colour.
PHP Code:
imagefill($image, 0, 0, $background);
Now we are going to add the random CAPTCHA code to the image. A difference here is the separate characters will be set at an angle, just so that it isn't TOO clear to read, but also not difficult. Also we will use a function that allows you to specify your own font for the image. You'll need to either get a font from your computer, or download one from a website (DAFont.com is a good source for free fonts) and upload it to your server, preferably in the same folder as
captcha.php.
To get different angles for the characters, we'll go through a loop and set our
$angle variable to be different after each loop (The loop will loop through the amount of times you've specified in the
$length variable, in this case, 6.
PHP Code:
for($i = 1; $i <= $length; $i++) {
$counter = rand(1, 2);
if ($counter == 1) {
$angle = rand(0, 45);
}
if ($counter == 2) {
$angle = rand(315, 360);
}
imagettftext($image, rand(14, 20), $angle, ($i * 25), 30, $text, "templates/ChalkboardBold.ttf", substr($code, ($i - 1), 1));
}
What this does, is simply... after a loop has happened,
$counter is set to either 1 or 2, if it is 1 then
$angle will equal a number between 0 and 45 and if it is 2, it will equal a number between 315 and 360.
Now I'm going to go through the parameters of the
imagettftext function.
- $image is the image you will be using, you specified it earlier
- This is the size of the font
- The set angle
- The X co-ordinates
- The Y co-ordinates
- The text colour
- The path to your font file
- The text output
Okay so now you should have your image, with a background and font colour, as well as the actual CAPTCHA code on the image as well.
Optional: You could add a border to your image, in my opinion it makes it look better, but as it says, this step is optional. To do this we use a new function called
imagerectangle
PHP Code:
imagerectangle($image, 0, 0, $width - 1, $height - 1, $text);
The numbers in this function relate to the upper and lower co-ordinates of X and Y. If you minus 1 from the width and height, it will shrink the image by a pixel and show the rectangle behind it, which gives it the "border" effect.
This step is important, without it you can't view the image, because your working on a PHP file, and the browser will recognise it as a PHP file, and this is an image, so you need to make the browser recognise it as an image, and we do that by using the
header function and changing the content type.
PHP Code:
header("Content-Type: image/png");
Now the page will act as if it is a PNG file. You could use
image/jpg or
image/gif if you wish, but for this we're using a PNG.
Now that we have everything done and all put together, we need to output the image using a special function called
imagepng, like before, if you decide to use JPG or GIF, change the name of the function to represent your desired extention. (I.E. JPG =
imagejpg)
[php]
imagepng($image);
[/php
Now that we have our image done and ready to use, let's free up the resource used and 'destroy' the image (don't worry, it will still show up)
PHP Code:
imagedestroy($image);
} // End function
Something I did after the function was this:
PHP Code:
!isset($_GET['chars']) ? captcha() : captcha($_GET['chars']);
Basically is
chars is not set, it will output the CAPTCHA with the defaulted length, otherwise, it will display it with the number specified by you.
Now save this file, and try it out, open up your browser and point to the file and fingers crossed that it works! Any problems and let us know!
Using the script in your site and verifying it
Ok so you have the script, now you want to use it to prevent attacks on your forms. First get the file with the form you will be using it on. Anywhere in the code, add another input box, this will be used to type in what you see in the CAPTCHA code.
html Code:
<input type="text" name="captcha_confirm" />
Above (or below) that, add your CAPTCHA image to it. As we made the CAPTCHA file into an image, we can use the
img tag to display it.
html Code:
<img src="path/to/captcha.php" />
Now you should have your CAPTCHA code displayed, woo!
Verifying
This tutorial assumes that when you submit your form, it uses PHP to process the form to do... whatever it does. Now around the code your using, you need to check if the CAPTCHA matches what was typed in. I will use an example that I did.
PHP Code:
if($_POST['captcha_confirm'] == $_SESSION["captcha"]) {
// Update user's e-mail address
mysql_query(sprintf("UPDATE members, settings SET
settings.hide_email = '%d',
members.email = '%s'
WHERE members.id AND settings.member_id = '%d'",
(isset($_POST['hide_email']) ? 1 : 0),
$_POST['confirm_email'],
$_COOKIE['userID']
)) or die(mysql_error());
// Above is the code I have... your code will be whatever it was, just wrap the if statement around it
}
else {
echo 'Captcha did not match';
}
Now when you submit your form, and if the CAPTCHA is wrong, you should get an error instead of your code being processed.
So that's all their is to it, I hope this tutorial is helpful to you, if you have any problems, please just ask, we're here to help!
Full code
PHP Code:
<?php
session_start();
//--------------------
// CAPTCHA Function
//--------------------
function captcha($length = 6) {
$length = isset($_GET['chars']) ? $_GET['chars'] : 6;
// Let's generate a totally random string using md5
$hash = md5(rand(0, 999));
// We don't need a 32 character long string so we trim it down to 5
$code = substr($hash, 15, $length);
// Set the session to store the security code
$_SESSION["captcha"] = $code;
// Set the image width and height
$width = 200;
$height = 50;
// Create the image resource
$image = imagecreate($width, $height);
// Random RGB colours
$rgb1 = rand(0, 255);
$rgb2 = rand(0, 255);
$rgb3 = rand(0, 255);
$background = imagecolorallocate($image, $rgb1, $rgb2, $rgb3);
$text = imagecolorallocate($image, ($rgb1 - 50), ($rgb2 - 50), ($rgb3 - 50));
// Make the background colour
imagefill($image, 0, 0, $background);
// Add randomly generated string in the image
for($i = 1; $i <= $length; $i++) {
$counter = rand(1, 2);
if ($counter == 1) {
$angle = rand(0, 45);
}
if ($counter == 2) {
$angle = rand(315, 360);
}
imagettftext($image, rand(14, 20), $angle, ($i * 25), 30, $text, "templates/ChalkboardBold.ttf", substr($code, ($i - 1), 1));
}
// Add a border
imagerectangle($image, 0, 0, $width - 1, $height - 1, $text);
// Tell the browser what kind of file is come in
header("Content-Type: image/png");
// Output the newly created image in jpeg format
imagepng($image);
// Free up resources
imagedestroy($image);
}
!isset($_GET['chars']) ? captcha() : captcha($_GET['chars']);
?>