How to create captcha in PHP using GD library

Tutorials

Today I will tell you about very important thing – captcha protection. Usually this is very important to prevent automated sign-ups in your registration forms, comment spam in blogs and guestbooks, or another brute force attacks. I will give sample how to draw protection image using our hands.

Here are samples and downloadable package:

Live Demo

[sociallocker]

download in package

[/sociallocker]


Ok, download the example files and lets start coding !


Step 1. HTML

As usual, we start with the HTML.

This is our main page code.

index.html

01 <script src="js/jquery.min.js"></script>
02 <script src="js/md5.js"></script>
03 <script src="js/main.js"></script>
04 <link rel="stylesheet" href="templates/css/main.css" type="text/css" />
05 <div class="captcha_example">
06     <h3><a href="#">Captcha generation using GD, using MD5 to encrypt security text</a></h3>
07     <div>
08         <div style="margin-bottom:10px;">
09             <h4>Security image:</h4>
10             <img src="captcha.php" class="form_captcha" />
11             <div class="lines">Verification (Type what you see):</div>
12             <input type="text" name="captcha" value="" class="captcha" />
13             <button onclick="checkCaptcha()">Check it</button>
14         </div>
15         <p>
16             Current sample draw security image using GD library, each time when page loads it show different symbol-digit combinations. This combination processing through MD5 encription and storing in cookies. So you will able to check cookies after (where it necessary). In my sample I checking it using javascript. Try it!
17         </p>
18     </div>
19 </div>

To display captcha (security image) we will just draw image with php-source: captcha.php. It will generate image for us. Generated text will processed via MD5 and stored in cookies to following recognition and checking.

Step 2. CSS

Here are used CSS styles.

templates/css/main.css

1 body{background:#eee;font-family:VerdanaHelveticaArialsans-serif;margin:0;padding:0}
2 .captcha_example{background:#FFF;width:865px;font-size:80%;border:1px #000 solid;margin:0.5em 10% 0.5em;padding:1em 2em 2em;-moz-border-radius: 3px;-webkit-border-radius: 3px}
3 .lines{margin:10px 0}

Step 3. JS

Here are necessary JS files to our project.

js/main.js

01 function getCookie(c_name) {
02     if (document.cookie.length>0) {
03         c_start=document.cookie.indexOf(c_name + "=");
04         if (c_start!=-1) {
05             c_start=c_start + c_name.length+1;
06             c_end=document.cookie.indexOf(";",c_start);
07             if (c_end==-1) c_end=document.cookie.length;
08             return unescape(document.cookie.substring(c_start,c_end));
09         }
10     }
11     return "";
12 }
13 function checkCaptcha() {
14     // check captcha
15     var sInsCaptcha = calcMD5($('.captcha').val());
16     var sCookieCaptcha = getCookie('strSec');
17     if (sInsCaptcha == sCookieCaptcha) {
18         alert('Wow, great, you enter correct captcha');
19     else {
20         alert('Sorry, but wrong');
21     }
22 }

We will using getCookie function to get cookies information, and checkCaptcha to validate captcha.

js/jquery.min.js and js/md5.js

This is common files – jQuery library with addon for working with MD5. No need to give full code of that file here. It always available as a download package

Step 4. PHP

Ok, here are all used PHP file:

index.php

01 <?php
02 ob_start();
03 $chars array("a","A","b","B","c","C","d","D","e","E","f","F","g","G","h","H","i","I","j","J",
04                "k","K","L","m","M","n","N","o","p","P","q","Q","r","R","s","S","t","T",
05                "u","U","v","V","w","W","x","X","y","Y","z","Z","2","3","4","5","6","7","8","9");
06 $textstr '';
07 for ($i = 0, $length = 5; $i $length$i++)
08    $textstr .= $chars[rand(0, count($chars) - 1)];
09 $hashtext = md5($textstr);
10 setcookie('strSec'$hashtext, 0, '/');
11 if (produceCaptchaImage($textstr) != IMAGE_ERROR_SUCCESS) {
12     // output header
13     header( "Content-Type: image/gif" );
14     header("Expires: Mon, 21 Jul 2010 05:00:00 GMT");
15     header("Last-Modified: " gmdate("D, d M Y H:i:s") . " GMT");
16     header("Cache-Control: no-store, no-cache, must-revalidate");
17     header("Cache-Control: post-check=0, pre-check=0", false);
18     header("Pragma: no-cache" );
19     // output error image
20     @readfile('captcha/captcha_error.gif');
21 }
22 ob_end_flush();
23 function produceCaptchaImage($text) {
24     // constant values
25     $backgroundSizeX = 2000;
26     $backgroundSizeY = 350;
27     $sizeX = 200;
28     $sizeY = 50;
29     $fontFile "captcha/verdana.ttf";
30     $textLength strlen($text);
31     // generate random security values
32     $backgroundOffsetX = rand(0, $backgroundSizeX $sizeX - 1);
33     $backgroundOffsetY = rand(0, $backgroundSizeY $sizeY - 1);
34     $angle = rand(-5, 5);
35     $fontColorR = rand(0, 127);
36     $fontColorG = rand(0, 127);
37     $fontColorB = rand(0, 127);
38     $fontSize = rand(14, 24);
39     $textX = rand(0, (int)($sizeX - 0.9 * $textLength $fontSize)); // these coefficients are empiric
40     $textY = rand((int)(1.25 * $fontSize), (int)($sizeY - 0.2 * $fontSize)); // don't try to learn how they were taken out
41     $gdInfoArray = gd_info();
42     if (! $gdInfoArray['PNG Support'])
43         return IMAGE_ERROR_GD_TYPE_NOT_SUPPORTED;
44     // create image with background
45     $src_im = imagecreatefrompng( "captcha/background.png");
46     if (function_exists('imagecreatetruecolor')) {
47         // this is more qualitative function, but it doesn't exist in old GD
48         $dst_im = imagecreatetruecolor($sizeX$sizeY);
49         $resizeResult = imagecopyresampled($dst_im$src_im, 0, 0, $backgroundOffsetX$backgroundOffsetY$sizeX$sizeY$sizeX$sizeY);
50     else {
51         // this is for old GD versions
52         $dst_im = imagecreate( $sizeX$sizeY );
53         $resizeResult = imagecopyresized($dst_im$src_im, 0, 0, $backgroundOffsetX$backgroundOffsetY$sizeX$sizeY$sizeX$sizeY);
54     }
55     if (! $resizeResult)
56         return IMAGE_ERROR_GD_RESIZE_ERROR;
57     // write text on image
58     if (! function_exists('imagettftext'))
59         return IMAGE_ERROR_GD_TTF_NOT_SUPPORTED;
60     $color = imagecolorallocate($dst_im$fontColorR$fontColorG$fontColorB);
61     imagettftext($dst_im$fontSize, -$angle$textX$textY$color$fontFile$text);
62     // output header
63     header("Content-Type: image/png");
64     // output image
65     imagepng($dst_im);
66     // free memory
67     imagedestroy($src_im);
68     imagedestroy($dst_im);
69     return IMAGE_ERROR_SUCCESS;
70 }
71 ?>

Here are several comments by code:

In start we will define array of used characters – $chars. After, we will compose string (5 letters) with random characters. After, will MD5 this result string and save it into cookies. We will use this to more security. So any bot or special script will unable to find this key even after detail investigation of result page.

produceCaptchaImage is main function which will draw our captcha. It take just 1 param – text which we going to draw. We will using GD library to draw. We will randomly choose position to text in captcha, angle (+- 5 degrees), font color. After will get our background image which will mage reading of our code more difficult, and, will draw result text on this image.


Live Demo

Conclusion

Today I told you how to create our own captcha – security image. I sure that you will use it in your projects. Quite any serious project using it to protect spamming. Good luck!

Rate article