CAPTCHA Tutorial

cursedpsp

New Member
Messages
237
Reaction score
0
Points
0
Hi, ill show you how to make a simple captcha with PHP.

First of all you will need a background image, i have one here that i use
captcha.png

http://script-centre.co.cc/sources/captcha.png

150x25 normally is perfect for the job.

First of all you will need to create the file (duh) so i called mine "captcha.php" (will require the php, not png.)

And now when you have done that we can start the session, so we can then apply the session keys later.

Code:
   <?php
       // Start the session
       session_start();
   ?>

Once we have done that, (great), we can make a randomising string with an encryption function called md5. MD5 does not randomise by itself (if you wish to randomise without MD5 then please consider the rand() function) so you will need to encrypt the TIME.

Code:
   $rand = md5(microtime() * time() * mktime());

You can set it out in any way you want, but microtime() is recommended since it updates every 10th of a second, and time() updates every second, which is not recommended since you can refresh a browser more than 1 time in a second.

You can use "$rand = md5(microtime() * 41 / 8 + 1);" and it would still be random, but i used all the time functions because it will create it truly random :D

Next, we would need to shorten that to a limited number of letters and numbers.

Code:
   $string = substr($rand, 0, 10);

Basically, we get $rand, start from point 0 and grab only 10 characters. You can change it to anything (less than the MD5 string ofcorse), - 5, 8 and 10 are usually the best option.

And now we should store that into a session array.

Code:
   $_SESSION['captcha'] = $string;

Quite straight forward.

--- Now we have done the basic stuff, we can get making the image now!

First off then, you will need to base the image on something.

Code:
 $img = imagecreatefrompng("captcha.png");
That is if your background is "captcha.png" and it is a MIME type of png.

If you wanted a solid colour image needless of a gradient or fancy stuff then you can simply create your own "PHP Canvass" thing and declare the background colour

Code:
 $img = imagecreate(150, 25); # Create image by standard of 100 x 25 pixels
 $backgroundcolour = imagecolorallocate($img, 0, 100, 150);

Which will create a blank image canvass with a shade of a nice blue (the same blue as the bottom of the gradient of my one)

Now that we have created our "base" image we can now start adding some stuff to it, but first we will need to declare the variables for our colours.

Code:
 $linecolour = imagecolorallocate($img, 250, 250, 250);
 $textcolour = imagecolorallocate($img, 0, 0, 0);

The first variable will create a colour for the lines, just slightly off perfect white (255).
The second variable will create a colour for the text, black.

Other variables that we will require would be these
Code:
 // Other variables
 $lines = 10;
 $i = 1; # Don't change
 $xcentre = (150 / 2) - ((strlen($string) / 2) * imagefontwidth(5)); # Centre the text X
 $ycentre = (25 - imagefontheight(5)) / 2; # Centre the text Y

The first variable is how many lines we will want. 10 is fine.
The second variable is our starting point for our while loop, should not really need to be different to 1
The "$xcentre" is a formula i have been using for years, it is used to centre the text in the canvass. Heres a quick run through:
$xcentre = (WIDTH / 2) - ((strlen($STRING) / 2) * imagefontwidth(FONTSIZE));
The "$ycentre" is pretty much the same as the one above, apart from "25" is the image height.

Now we come onto repeating the lines for the image - providing how many lines we want (as we said in the variable) will be how many lines there will be

Code:
 // Repeat the lines
 while($i <= $lines){
     $randxs = rand(0, 150); # Random X start point
     $randys = rand(0, 0); # Random Y start point
     $randxe = rand(0, 150); # Random X end point
     $randye = rand(0, 50); # Random Y end point
     
     imageline($img, $randxs, $randys, $randxe, $randye, $linecolour);
     $i += 1;
 }

Basically, there is not much to say in this - but it will create the lines at different start and end points, and then it would loop through until "$i" is less than or equal too "$lines" (<=)

How we would output the text is just by using one function which is "imagestring()"

Code:
 imagestring($img, 5, $xcentre, $ycentre, $string, $textcolour);

The first perameter is just the base image
The second "number" as we may call it is the font size - ranging from 1 to 5 where 1 being smallest and 5 being largest. Size 3 is a bolder version of size 2, and size 5 is a bolder version of size 4.
$xcentre and $ycentre are the variables declared earlier that we made to centre the text.
$string is the shortened version of the MD5 we made. This perameter is where we can enter text, so if we wanted to display "Captcha: 3h42ih2" or something we could use

Code:
 imagestring($img, 5, $xcentre, $ycentre, "Captcha: $string", $textcolour);

And yes we can use variables inside quotes, its only arrays that need to be outside quotes.
The final perameter is the text colour.

And finally, to output the image!

Code:
 // Send headers (save time laters)
 header("Content-Type: image/png");
 imagepng($img); # Echo image out
 imagedestroy($img); # Destroy image

Comments make it quite self-explanetory.
image can be outputted to what ever format you like, if you dont know the content type of a file just google for example "MIME Type of JPG"

So the final outcome will produce this
captcha.php
- with randomising lines and string.

Here is the complete code

Code:
 <?php
     // Start the session
     session_start();
     
     // Generate randomness from MD5
     $rand = md5(microtime() * time() * mktime());
     
     // String for randomness
     $string = substr($rand, 0, 10);
     
     // Set the session
     $_SESSION['captcha'] = $string;
     
     /*
         @ NOW WE CAN MAKE THE IMAGE!!
     */
     
     $img = imagecreatefrompng("captcha.png");
     
     // Colours
     $linecolour = imagecolorallocate($img, 250, 250, 250);
     $textcolour = imagecolorallocate($img, 0, 0, 0);
     
     // Other variables
     $lines = 10;
     $i = 1; # Don't change
     $xcentre = (150 / 2) - ((strlen($string) / 2) * imagefontwidth(5)); # Centre the text X
     $ycentre = (25 - imagefontheight(5)) / 2; # Centre the text Y
     
     // Repeat the lines
     while($i <= $lines){
         $randxs = rand(0, 150); # Random X start point
         $randys = rand(0, 0); # Random Y start point
         $randxe = rand(0, 150); # Random X end point
         $randye = rand(0, 50); # Random Y end point
         
         imageline($img, $randxs, $randys, $randxe, $randye, $linecolour);
         $i += 1;
     }
     
     // Echo text
     imagestring($img, 5, $xcentre, $ycentre, $string, $textcolour);
     
     // Send headers (save time laters)
     header("Content-Type: image/png");
     imagepng($img); # Echo image out
     imagedestroy($img); # Destroy image
 ?>

______________________

To make a user input to make the user enter information and check whether it is valid or not

Code:
<?php
    session_start();
?>
<img src="captcha.php" border="0" />
<form action="shoutboxFrame.php" method="post">
    <input type="text" name="key" />
    <input type="submit" value="Submit" />
</form>
<?php
    if($_SESSION['captcha'] == $_POST['key']){
        echo "Valid captcha key!";
    }
    else{
        echo "Invalid";
    }
?>

Obviously this wont the whole thing, but is just the basic page and contains the basic requirements to check for the key. Image, textbox, php.

_____________________

This tutorial took an agonising 2 hours and comments or reputation is greatly appreciated!
http://script-centre.co.cc - for extra applications
 

snowball88

New Member
Messages
4
Reaction score
0
Points
0
Nice tutorial. I encountered the following error:
Fatal error: Call to undefined function imagecreatefrompng()
The hosting plan has provide the GD library, so I have no clue why it does not work. I would appreciate if someone can point me at the right direction. thanks.
 

snowball88

New Member
Messages
4
Reaction score
0
Points
0
Thanks for the quick reply. This is something that I have missed out. My request for a PHP version change to "intermediate" has been submitted and is pending review. I will post again once it work.
 

snowball88

New Member
Messages
4
Reaction score
0
Points
0
I have upgraded the PHP to version 2 "Intermediate" and it now works brilliantly. Thanks again for the help. Cheers.
 

Twinkie

Banned
Messages
1,389
Reaction score
12
Points
0
Very useful, thanks. I was planning to use this, and never had the time to make it myself.
 
Top