Creating strong captcha with PHP

While was looking for a captcha class for PHP, I found securimage. It's great but not very strong "out of the box".

With some modifications, I came up with a very strong way to create captcha directly with PHP. It use a variety of fonts, backgrounds and a dictionnary of words from a random book on Gutenberg. To make sure the captcha is readable, a function calculate the luminosity difference between the text and 2 colors in the background.

You can try the captcha on this page

Installation

  • Getting securimage

Download from this page. Make sure you can use it by running "server_test.php" (you need GD and TTF enabled with your PHP installation).

  • Getting backgrounds, fonts and dictionnary

Extract the zip file in the root folder of securimage, it should add three folders : background, ttf and words.

securimage_extra.zip

  • Creating a test page

In the root folder of securimage, replace securimage_show.php with this :

<?php
include 'securimage.php';
 
//Function to return a random color
function randColor()
{
  $chars = "01234567890ABCDEF";
  for($i=0;$i<6;$i++) {
    $pos = rand(0,15);
    $str .= $chars[$pos];
  }
  return "#".$str;
}
 
//Function to calculate the difference of luminosity between 2 RGB colors
function lumdiff($R1,$G1,$B1,$R2,$G2,$B2){
  $L1 = 0.2126 * pow($R1/255, 2.2) + 0.7152 * pow($G1/255, 2.2) + 0.0722 * pow($B1/255, 2.2);
 
  $L2 = 0.2126 * pow($R2/255, 2.2) + 0.7152 * pow($G2/255, 2.2) + 0.0722 * pow($B2/255, 2.2);
 
  if($L1 > $L2){
    return ($L1+0.05) / ($L2+0.05);
  }else{
    return ($L2+0.05) / ($L1+0.05);
  }
}
 
//Return RGB code according to HTML color code
function html2rgb($color)
{
  if ($color[0] == '#') {
    $color = substr($color, 1);
  }
 
  if (strlen($color) == 6) {
    list($r, $g, $b) = array($color[0].$color[1], $color[2].$color[3], $color[4].$color[5]);
  } elseif (strlen($color) == 3) {
    list($r, $g, $b) = array($color[0].$color[0], $color[1].$color[1], $color[2].$color[2]);
  } else {
    return false;
  }
 
  $r = hexdec($r); $g = hexdec($g); $b = hexdec($b);
 
  return array($r, $g, $b);
}
 
//Select a random background and return 2 color from the palette
function randBg()
{
  $backgrounds = array('0b0c0e-404a4c', '2b241a-15151d', '2c6dfc-dae0fa', '0163a4-44a92e', '692f3e-f3cac8', '721c04-cd2d01', '333860-0d030b', '791611-062544', 'a86c64-ffffff', 'fa2e49-573fff');
  return $backgrounds[rand(0, count($backgrounds) - 1)];
}
 
$img = new securimage();
 
//Random string lenght between 5 and 10
$codeLenght = rand(5, 10);
$img->code_length = $codeLenght;
 
//Choose a random word dictionnary
$img->wordlist_file = './words/words_' . $codeLenght . '_' . rand(0, 10) . ".txt";
 
//Put text separation so it doesnt overlap
$img->text_minimum_distance = 26;
$img->text_maximum_distance = 30;
 
//Random font
$img->ttf_file = './ttf/' . rand(1,8) . '.ttf';
 
//resize captcha according to word lenght
$img->image_width = $codeLenght * 33;
 
//Set transparency to zero
$img->text_transparency_percentage = 0;
 
//Dont draw lines
$img->draw_lines = false;
 
//Select a random background and get the 2 colors
$bgColors = randBg();
$bgColorsParts = explode('-', $bgColors);
$bgColors1 = $bgColorsParts[0];
$bgColors2 = $bgColorsParts[1];
 
//Get background RGB colors
$bgColors1RGB = html2rgb($bgColors1);
$bgColors2RGB = html2rgb($bgColors2);
 
while (!$finalTextColor) {
  //Pick a random text color
  $textColor = randColor();
 
  //Get RGB color
  $textColorRGB = html2rgb($textColor);
 
 
  $lumdiff1 = lumdiff($textColorRGB[0], $textColorRGB[1], $textColorRGB[2], $bgColors1RGB[0], $bgColors1RGB[1], $bgColors1RGB[2]);
  $lumdiff2 = lumdiff($textColorRGB[0], $textColorRGB[1], $textColorRGB[2], $bgColors2RGB[0], $bgColors2RGB[1], $bgColors2RGB[2]);
 
  if ($lumdiff1 > 2 && $lumdiff2 > 2) {
    $finalTextColor = $textColor;
  }
}
 
//Set text and arc colors the same
$img->multi_text_color = $finalTextColor;
$img->arc_line_colors = $finalTextColor;
 
//The background image
$bgImage = './background/' . $bgColors . '.jpg';
 
//Show the captcha
$img->show($bgImage);

  • Testing

Simply run example_form.php in your favorite browser

  • Feedbacks

Feel free to post comments!!!

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Интересная информация.

 Машина - это не роскошь, а вариант движения - http://women-auto.ru . И предполагается приобрести красивое авто, тогда следует изучить вопрос - http://vip-carinfo.ru , посмотреть автообзоры - http://autositeinfo.ru . И потом можно в банк за автокредитом...

Интересная информация.

 Авто - это не роскошь, а средство передвижения - http://women-auto.ru . И предполагается купить шикарное авто, тогда нужно изучить вопрос - http://vip-carinfo.ru , почитать автообзоры - http://autositeinfo.ru . И потом можно в банк за автокредитом...

re

i've been working on an open source PHP framework for some time, should be avail soon ;)

nice

ich, they indeed look nice and strong... haven't seen releases form you in a while, nice to know u're ok :P

pgn.ro