Captcha Script   

Captcha is used to keep web bots from exploiting pages that do things like create accounts or generate email.

The captcha images used on this site's contact page are generated by the PHP script shown below.The original came from the Web 1 Marketing site. It is published here (in modified form) under the GNU General Public License.

This modified version reduces the original to a single stand-alone file that supplies the key via session variables which can be accessed with, e.g., an Ajax-like callback. It corrects some bugs and also generates images with a lower likelihood of being unreadable by humans.

Download a .zip file rather than copying the text below (trust me).

<?php /* ============================ QuickCaptcha 1.0 - A bot-thwarting text-in-image web tool. Copyright (c) 2006 Web 1 Marketing, Inc. QuickCaptcha 1.1 - A modified version the above. Copyright (c) 2009 DT Software Engineering This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ============================ 1.1 This file was derived from the original and modified to be a single stand-alone file that employs session variables to allow retrieval of the key string via, e.g., an AJAX like callback. The image obfuscation code was also modified to reduce the likelihood of captcha images that were not human readable. Some other bugs were fixed as well. ============================ */ // The alphabet used to generate keys. No O, zero, or five. $sourceCharacters = 'ABCDEFGHIJKLMNPQRSTUVWXYZ12346789'; // Number of characters in the key. $keyLength = 6; // Number of obfuscation shapes to draw. Note that many // effectively disappear due to blending. $nTriangles = 4; $nEllipses = 14; $nLines = 10; $minLineWeightPixels = 2; $maxLineWeightPixels = 6; $minEllipseAxisPixels = 6; $maxEllipseAxisPixels = 22; // Percent values for color components in obfuscation objects // and key characters. $objectSaturation = 90; $objectFloor = 30; $characterSaturation = 80; $characterFloor = 10; // Normalize color paramenters $objClrCompCeil = 255 * ($objectSaturation / 100.0); $objClrCompFloor = 255 * ($objectFloor / 100.0); $charClrCompCeil = 255 * ($characterSaturation / 100.0); $charClrCompFloor = 255 * ($characterFloor / 100.0); // See PHP function imagecolorallocatealpha() 0-127 $objAlpha = 100; // Make the base key image // 5 is used as a representative character size $width = 3 * $keyLength * imagefontwidth (5); $height = 2.5 * imagefontheight (5); $image = imagecreatetruecolor ($width, $height); imagealphablending($image, true); //Make the key. $nSrcChars = strlen($sourceCharacters)-1; $keyString = NULL; for($i=0; $i < $keyLength; $i++) {    $cnum[$i] = $sourceCharacters{mt_rand(0, $nSrcChars)};    $keyString .= $cnum[$i]; } // Add string to image $rotated = imagecreatetruecolor (70, 70); $x = 0; for ($i = 0; $i < $keyLength; $i++) {    $srcBuff = imagecreatetruecolor (20, 20);    $destBuff = imagecreatetruecolor (40, 40);    $red = mt_rand($charClrCompFloor,$charClrCompCeil);    $green = mt_rand($charClrCompFloor,$charClrCompCeil);    $blue = 255 - sqrt($red * $red + $green * $green);    $color = imagecolorallocate ($srcBuff, $red, $green, $blue);    // Get a character of the color generated above.    imagestring($srcBuff, 5, 0, 0, $cnum[$i], $color);    // Resize character    imagecopyresized ($destBuff, $srcBuff, 0, 0, 0, 0, 25 + mt_rand(0,12), 25 + mt_rand(0,12), 20, 20);    // Rotate characters a little    $rotated = imagerotate($destBuff, mt_rand(-25, 25),imagecolorallocatealpha($destBuff,0,0,0,0));    imagecolortransparent ($rotated, imagecolorallocatealpha($rotated,0,0,0,0));    // Move characters around a little    $y = mt_rand(1, 3);    $x += mt_rand(2, 6);    imagecopymerge ($image, $rotated, $x, $y, 0, 0, 40, 40, 100);    $x += 22;    imagedestroy ($srcBuff);    imagedestroy ($destBuff); } $triangleRegionXmin = 0; $triangleRegionXmax = 0; $triangleSpan = $width*($nTriangles/$keyLength); for ($i = 0; $i < $nTriangles; $i++) {    //Draw the triagles in slightly overlapping (Xtweak) swaths (triangleSpan) across the image.    $triangleRegionXmax += $triangleSpan;    $triangleXtweak = $triangleRegionXmin -= mt_rand( 0, (imagefontwidth(5)/3) );    $vertices = array (       mt_rand($triangleXtweak,$triangleRegionXmax*1.1),mt_rand(-0.25*$height,$height*1.25),       mt_rand($triangleXtweak,$triangleRegionXmax*1.1),mt_rand(-0.25*$height,$height*1.25),       mt_rand($triangleXtweak,$triangleRegionXmax*1.1),mt_rand(-0.25*$height,$height*1.25) );    $color = imagecolorallocatealpha ($image, mt_rand($objClrCompFloor,$objClrCompCeil), mt_rand($objClrCompFloor,$objClrCompCeil), mt_rand($objClrCompFloor,$objClrCompCeil), $objAlpha);    imagefilledpolygon($image, $vertices, 3, $color);    $triangleRegionXmin += $triangleSpan; } for ($i = 0; $i < $nLines; $i++) {    $x1 = mt_rand(-$width*0.25,$width*1.25);    $y1 = mt_rand(-$height*0.25,$height*1.25);    $x2 = mt_rand(-$width*0.25,$width*1.25);    $y2 = mt_rand(-$height*0.25,$height*1.25);    $color = imagecolorallocatealpha ($image, mt_rand($objClrCompFloor,$objClrCompCeil), mt_rand($objClrCompFloor,$objClrCompCeil), mt_rand($objClrCompFloor,$objClrCompCeil), $objAlpha);    imagesetthickness ($image, mt_rand($minLineWeightPixels,$maxLineWeightPixels));    imageline($image, $x1, $y1, $x2, $y2 , $color); } for ($i = 0; $i < $nEllipses; $i++) {    $x1 = mt_rand(0,$width);    $y1 = mt_rand(0,$height);    $color = imagecolorallocatealpha ($image, mt_rand($objClrCompFloor,$objClrCompCeil), mt_rand($objClrCompFloor,$objClrCompCeil), mt_rand($objClrCompFloor,$objClrCompCeil), $objAlpha);    imagefilledellipse($image, $x1, $y1, mt_rand($minEllipseAxisPixels,$maxEllipseAxisPixels), mt_rand($minEllipseAxisPixels,$maxEllipseAxisPixels), $color); } //Store session variables to be retried by the client for validation. session_start(); $_SESSION['keylen'] = $keyLength; $_SESSION['key'] = $keyString; header('Content-type: image/png'); imagepng($image); imagedestroy($image); ?>