Captcha from scratch (PHP / GD)
2010-08-11 07:51 by Ian
/************************************************************************** * Author: J. Ian Lindsay * * File: captcha.php * * * * Generates a captcha and updates the session. Ensures that the captcha * * is readable and recurses if it isn't. * **************************************************************************/ require_once("include/session.php"); define('RENDER_WIDTH', 350); // How big an image to generate? define('RENDER_HEIGHT', 80); define('TEXTURE_PATH', "include/escher_grid_ps.jpg"); // File to draw background noise from. define('ANGLE_DEV', 25); // Maximum deviation from horizontal, in degrees. define('FONT_PATH', "include/courbd.ttf"); // Font to write the captcha text with. define('TEXT_SIZE', 20); // Pixel height of the text. define('DICT_PATH', "include/8-letter-words.txt"); // Path to the dictionary. define('C_RANGE_LOW', 0); // The darkest any random color channel can be. define('C_RANGE_HIGH', 190); // The brightest any random color channel can be. // Return a random word from a comma-delimited dictionary file located at DICT_PATH. function randomWordFromDict(){ $read = file_get_contents(DICT_PATH); $words = explode(",", $read); return($words[rand(0,count($words)-1)]); } // Copy a region of the desired size from the source texture file at random. This will prevent // bots from subtracting a known-texture to remove visual noise. // If a texture file is specified that is too small, it will not use a texture, but will return // an image anyway. function cropFromTextureFile(){ $img = imagecreatefromjpeg(TEXTURE_PATH); $area = imagecreatetruecolor(RENDER_WIDTH, RENDER_HEIGHT); imagefill($img,0,0,imagecolorallocatealpha($img, 255,255,255,0)); $tex_width = imagesx($img); $tex_height = imagesy($img); if(($tex_width > RENDER_WIDTH) && ($tex_height > RENDER_HEIGHT)){ imagecopy($area, $img, 0, 0, rand(0,$tex_width-RENDER_WIDTH), rand(0,$tex_height-RENDER_HEIGHT), RENDER_WIDTH, RENDER_HEIGHT); } imagerectangle($area, 0, 0, RENDER_WIDTH - 1, RENDER_HEIGHT - 1, imagecolorallocate($area, 0, 0, 0)); return($area); } // Generates a captcha and updates a session variable accordingly. function generateCaptcha(){ $img = cropFromTextureFile(); $image_text = randomWordFromDict(); $text_color = imagecolorallocate($img,rand(C_RANGE_LOW,C_RANGE_HIGH),rand(C_RANGE_LOW,C_RANGE_HIGH),rand(C_RANGE_LOW,C_RANGE_HIGH)); $output = imagettftext($img, TEXT_SIZE, (rand((0-ANGLE_DEV),ANGLE_DEV)), rand(0,RENDER_WIDTH-(TEXT_SIZE*strlen($image_text))), rand(TEXT_SIZE,RENDER_HEIGHT-TEXT_SIZE), $text_color,FONT_PATH, $image_text); $_SESSION['captcha'] = $image_text; // Must happen before recursion. if(($output[2] > RENDER_WIDTH) || ($output[4] > RENDER_WIDTH) || (($output[3]+(TEXT_SIZE/2)) > RENDER_HEIGHT) || ($output[5] < (TEXT_SIZE/2))){ $img = generateCaptcha(); } return($img); } header("Content-type:image/jpeg"); header("Content-Disposition:inline ; filename=secure.jpg"); imagejpeg(generateCaptcha());
Click the image for a different word.
Previous: Nitrogen Triiodide
Next: Lojban parser