Captcher
© 2006-9 Gecko Tribe, LLC
Captcher Homepage
Captcher is a PHP script that generates and verifies
captchas.
Capiche? :-)
Captchas are images designed to prevent automated scripts from submitting web forms,
and are used to prevent spamming via email forms and online forums, and other such problems.
Requirements
- PHP with GD support for outputting GIFs (any reasonably up to date PHP installation)
- mySQL
- Support for Perl or PHP cron jobs recommended --
otherwise you'll need to run the cleanup script (which cleans unsolved captchas out of the database)
manually on a regular basis or have a regularly visited webpage trigger it
Installation
- Get some GD fonts.
Use only fonts with a complete set of uppercase and lowercase letters and digits (some font don't contain a full character set).
- Although Captcher is not case sensitive,
it displays both upper and lowercase letters for more variety.
- If you can't find any GD fonts or if you just want to create your own,
download GD FontMaker.
It makes creating a font incredibly easy.
(Be sure to save your fonts with the filename extension ".gdf".)
- Decide where on your server to install the fonts and scripts (other than captcher.php--it should go in a different location)
and create the directory if necessary.
I recommend putting everything except captcher.php outside of your web directory if possible,
though some PHP installations will generate error messages if you do.
- Enter the path to the directory chosen the previous step in the configuration section at the top of captcher.php.
- Do NOT end the path with a "/" -- just enter everything up to the directory name.
- Do NOT enter a URL (eg. http://example.com/captcher) -- the path should be something like
"/home/yourusername/catpcher" or "c:/www/captcher", etc.
- Create a subdirectory named "gdfonts" inside the directory you chose and upload the fonts to that subdirectory.
- Enter the names of the fonts (the name of the file without the ".gdf")
in the "$fonts" or "$bgfonts" array in the configuration section at the top of captcher.php.
- Fonts listed in $fonts may be used for either captcha or background letters.
- Those listed in $bgfonts will only be used for background letters --
you may want to stick with more readable fonts for $fonts to avoid making your captchas too difficult.
- Be sure to enclose each font name in quote marks (double or single -- it doesn't matter),
and end each line except the last with a comma.
- You don't have to enter anything in $bgfonts --
if you don't, delete the font names, but DON'T delete "$bgfonts=array();"
- Create a mySQL database (if you don't already have one),
and then execute the contents of captcher.sql to create a table for Captcher.
- Decide whether you want to use the Perl (.pl) or PHP version of captcher-clean to periodically delete old entries from the database.
If you can run cron jobs on your server, captcher-clean.pl may be easier to set up.
If not, captcher-clean.php may be easier to set up.
- Enter the database and table names in the configuration sections of captcher-utils.php
and either captcher-clean.pl or captcher-clean.php (whichever you decided to use).
In captcher-utils.php and captcher-clean.php,
enter them as "database-name.table-name" (ie. the database and table names separated by a dot).
In captcher-clean.pl, the database and table names are entered separately.
- Enter the path to a PHP script that opens a mySQL connection in the configuration section of captcher-utils.php.
If you don't already have such a script, use captcher-mysql.php (enter your username and password in that file).
- If you wish to modify the list of characters that may be used in the captcha, edit $captcherallowedchars in captcher-utils.php.
Depending on the fonts you use, some characters may be difficult to distinuish from each other, and should be omitted.
- Enter your database username and password in captcher-clean.pl or captcher-clean.php (whichever you decided to use).
- Upload captcher-utils.php, captcher-clean.pl or captcher-clean.php, and captcher-mysql (if you're going to use it) to the directory created in step 2.
- Upload captcher.php to a web-accessible location on your server (I put it in my "img" directory, since it's going to output images).
- If using captcher-clean.pl, make it executable by setting the access permissions to 755 (for a Linux/UNIX/BSD system)
or whatever is necessary for your server's operating system.
Ask your web host if you need help doing that.
- If you can run cron jobs, set up a cron job to run captcher-clean.pl (you did take my advice and choose captcher-clean.pl, right?)--once an hour if possible.
Ask your web host if you need help doing that.
- If you can't run cron jobs, pick a PHP webpage on your site that's accessed regularly, but not too regularly
(about once an hour is great, but it's not terribly critical if it's more or less often).
Add the following code (adjusting the path as necessary) to the end of that file (you did take my advice and choose captcher-clean.php, right?):
<?php include_once '/home/yourusername/captcher/captcher-clean.php'; ?>
Congratulations!
Unless you or I have goofed up, you've finished the hard part!
Use
An example of how to use Captcher can be found in sample-captcher.php.
The required operations are as follows:
In the form:
- Load captcher-utils.php (use PHP's "require_once").
- Create a key (MakeCaptchaKey) and store it with some captcha text in the database (StoreCaptcha or MakeCaptcha and StoreCaptcha).
- Output a hidden field in your form contaning the key.
- Output the captcha image (by passing the key to captcha.php).
- Prompt the user to type the colored letters from the image.
In the script that processes the form:
- Load captcher-utils.php.
- Check whether the captcha text was entered correctly (CheckCaptcha).
- If so, proceed with form processing.
- Otherwise, display an error message.
Points of note from sample-captcher.php:
- $utilpath must be a local file path, not a URL.
- $captcherURL must be a URL, not a local file path.
- The line "
if (CheckCaptcha($_REQUEST['key'],$_REQUEST['entered'])) {
" checks whether the user entered the correct captcha text.
If it matches, the captcha is automatically deleted from the database so that it cannot be reused.
- The line "
$newKey=MakeCaptchaKey();
" generates a 32 character key, but does not store it in the database.
- The line "
StoreCaptcha($newKey);
" automatically generates the captcha text and stores it and the key in the database.
There is no relationship between the key and the text, so no cryptographic exploit could determine the text from the key.
- The line '
<input type="hidden" name="key" value="<?php echo $newKey; ?>" />
' creates a hidden field in the form with the key.
- The line '
<img src="<?php echo $captcherURL; ?>?key=<?php echo $newKey; ?>" style="margin-top:8px;" />
' displays an HTML IMG tag which will display the captcha image.
Optional Configuration in captcher.php
- If you want to specify a fixed number of random letters to put in the background of the image,
enter that in the "$randomletters" setting.
To allow Captcher to decide the number of letters, leave it as "0".
- $textcolors specifies the colors that are used for the captcha letters.
You may alter, reduce, or add to them if you wish.
- $backgroundcolors specifies the colors that are used for the letters in the background.
You may alter, reduce, or add to them if you wish.
Function Reference
The following functions are defined in captcher-utils.php:
- MakeCaptcha($len=6)
Generates and returns a random string of uppercase letters.
The default length is 6:
$captcha=MakeCaptcha();
You may specify a different length by calling the function like this:
$captcha=MakeCaptcha(5);
- MakeCaptchaKey()
Generates and returns a 32 character string to be used as a database key to identify a particular captcha:
$key=MakeCaptchaKey();
- StoreCaptcha($key, $text='')
Stores a captcha and its associated key in the database.
If no captcha ($text) is specified, calls MakeCaptcha to generate one.
Returns the captcha text (whether generated by this function or not).
StoreCaptcha($key);
- CheckCaptcha($key, $entered, $delete=1)
Checks whether the captcha text entered by the user ($entered) matches the text stored in the database associated with the key ($key).
Returns 1 if they match and 0 if not.
The comparison is not case sensitive.
If $deleted = 1 (the default), deletes the captcha from the database if it matches.
CheckCaptcha($_REQUEST['key'], $_REQUEST['captcha']);
- GetCaptchaText($key)
Retrieves and returns the captcha text associated with the specified key.
$captcha=GetCaptchaText($_REQUEST['key']);