Helpful Information
 
 
Category: Post a PHP snippet
GD Image Validation [CAPTCHA]

I quickly wrote up a little class to do GD Image Validation, as I've seen a few people asking about it. GD Image Validation is useful for forms where you don't want automated submissions, such as email contact forms or registration forms. The class generates a random value and outputs it as an image, also setting it to a session variable to be compared with the user-entered data. I've posted the class, and the example below.


<?php
// Velox Letum (2005)
// [email protected]

class gd_verification {
var $im = NULL;
var $string = NULL;
var $height;
var $width;

function gd_verification ($height = 150, $width = 35, $sid = NULL) {
if ($sid != NULL) {
session_name($sid);
}

// Set image height/width
$this->height = $height;
$this->width = $width;

// Start session
session_start();
}
function generate_string () {
// Create random string
$this->string = substr(sha1(mt_rand()), 17, 6);

// Set session variable
$_SESSION['gd_string'] = $this->string;
}
function verify_string ($gd_string) {
// Check if the original string and the passed string match...
if ($_SESSION['gd_string'] === $gd_string) {
return TRUE;
} else {
return FALSE;
}
}
function output_input_box ($name, $parameters = NULL) {
return '<input type="text" name="' . $name . '" ' . $parameters . ' /> ';
}
function create_image () {
// Seed string
$this->generate_string();

$this->im = imagecreatetruecolor($this->height, $this->width); // Create image

// Get width and height
$img_width = imagesx($this->im);
$img_height = imagesy($this->im);

// Define some common colors
$black = imagecolorallocate($this->im, 0, 0, 0);
$white = imagecolorallocate($this->im, 255, 255, 255);
$red = imagecolorallocatealpha($this->im, 255, 0, 0, 75);
$green = imagecolorallocatealpha($this->im, 0, 255, 0, 75);
$blue = imagecolorallocatealpha($this->im, 0, 0, 255, 75);

// Background
imagefilledrectangle($this->im, 0, 0, $img_width, $img_height, $white);

// Ellipses (helps prevent optical character recognition)
imagefilledellipse($this->im, ceil(rand(5,$img_width - 5)), ceil(rand(0,$img_height)), 30, 30, $red);
imagefilledellipse($this->im, ceil(rand(5,$img_width - 5)), ceil(rand(0,$img_height)), 30, 30, $green);
imagefilledellipse($this->im, ceil(rand(5,$img_width - 5)), ceil(rand(0,$img_height)), 30, 30, $blue);

// Borders
imagefilledrectangle($this->im, 0, 0, $img_width, 0, $black);
imagefilledrectangle($this->im, $img_width - 1, 0, $img_width - 1, $img_height - 1, $black);
imagefilledrectangle($this->im, 0, 0, 0, $img_height - 1, $black);
imagefilledrectangle($this->im, 0, $img_height - 1, $img_width, $img_height - 1, $black);

imagestring ($this->im, 5, intval(($img_width - (strlen($this->string) * 9)) / 2), intval(($img_height - 15) / 2), $this->string, $black); // Write string to photo
}
function output_image() {
$this->create_image(); // Generate image

header("Content-type: image/jpeg"); // Tell the browser the data is a JPEG image

imagejpeg($this->im); // Output Image
imagedestroy($this->im); // Flush Image
}
}
?>

Then to use it I made an example (two files), the form:

<?php
// Velox Letum (2005)
// [email protected]

// Require the class code...
require ('gd_image_verify.php');

// Initialize class
$gd = new gd_verification();

if (isset($_POST['submit'])) {
if ($gd->verify_string($_POST['gd_string'])) {
$result = 'User input matches image string.';
} else {
$result = 'User input does not match image string.';
}
}
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>GD Image Verification Class Example</title>
<head>
<body>
<div style="text-align:center;">
<h1>GD Image Verification Class Example</h1>
<? echo $result; ?><br /><br />
<form name="gd_verify" method="POST" action="<? echo $PHP_SELF; ?>">
<img src="gd_image.php" alt="Verification Image" /><br /><br />
<? echo $gd->output_input_box('gd_string'); ?><br /><br .>
<input type="submit" name="submit" value="Submit" />
</form>
</div>
</body>
</html>


and the image output:

<?php
// Velox Letum (2005)
// [email protected]

// Require the class code...
require ('gd_image_verify.php');

// Initialize class
$gd = new gd_verification();

// Output image
$gd->output_image();
?>

Enjoy.

Looks spiffy. I think it can be done alot quicker with other methods, but deffinately for a person running a site based on class files and function files this would be perfect. I'm going to have to give this a try.

This image verification is called CAPTCHA. At first I thought this would validate image files...

Theres only problem i can see is that you are using session_register(), which is now deprecated. :)

@Element:
Really, when you break it down, it doesn't get much simpler than this. Classes are very useful for containing lots of code in an object. If you needed image validation on 2 pages, you just load this class into both pages and its all there for you, with no additional code.

I read the page on session_register() and removed it...I thought it was a way to initialize session variables so an E_NOTICE wouldn't pop up. I changed it.

Looks great but Is possible to validate the INPUT without SUBMIT? I talk about validate the INPUT and the CODE without $_POST I yalk about validate like a normal input. Regards

Why go to the overhead of creating a CAPTCHA Image that is supposed to be only human readable, when you are sending the value of the CAPTCHA in a cookie (plain text) that is machine readable?


function generate_string () {
// Create random string
$this->string = substr(sha1(mt_rand()), 17, 6);

// Set session variable
$_SESSION['gd_string'] = $this->string;
}

Am I missing something?

What you should do is link a session id to the CAPTCHA value, and save this value on the server side (db, file etc). That way the client machine never gets the value of the CAPTCHA, only the session id.

You can then use the session id to retrieve the value of the CAPTCHA when validating the clients response.

Session data is not sent to the user... only the session id is.

Session data is not sent to the user... only the session id is.
Oh wow thanks!
Somehow I was seeing $_COOKIE instead of $_SESSION. Urrggg, I blame the coffee.

Hi there, I'm a bit new on this, but I would like to also use this for my form as in the past they have spammed me a lot through traditional forms and even the hosting company made me take out the form.

So I have implemented this supercode in my website, but seems not to create the image, what can be the problem? I have my gd_enabled on the server.

In my info.php states: 'with-gd' '--enable-gd-native-ttf' '--without-gdbm'

I supose the server has enough to run with this code right?

many zanx!

welcome here!

it always helps if you show us the code that you used...

this
action="<? echo $PHP_SELF; ?>" should be like

action="<?php echo $_SERVER['PHP_SELF']; ?>
i think :thumbsup:

Great thanks.

I'm now collecting useful php classes object.

Then I will build Php Class Framework which will include all the author info.

I have a plan coz I want it like Ajax framework.

Any comments will be welcomed. pm me. thanks.

I am not very experienced at scripting with PHP, but I'm trying to get this to work within Formmail. Is that possible? My forms at my web site get a ton of Spam, and I was hoping to get rid of that without having to re-invent the wheel. Is there a way to do this? If you go to http://www.cyberscape.ca/contact_us.php you can see what I am doing (and maybe what I'm doing wrong).

Thanks in advance!

It looks like you managed to implement it alright, or are you still struggling?

jr_yeo: That file is a non-issue as it was only an example written straight into the text editor here on CF.

hey i am new as well, and i dont know am i doing wrong or why do i get a red cross instead of a gd image, although i do have gd installed on my server.

You do no that that can be read easy by a OCR (http://en.wikipedia.org/wiki/Optical_character_recognition)

theres a good one on (http://www.puremango.co.uk/cm_php_captcha_script_113.php)

hi, i have run the code given by you for image verification....

but it is not displaying the image...

please help me how to display image for above code...

plzz help........

hi, i have run the code given by you for image verification....

but it is not displaying the image...

please help me how to display image for above code...

plzz help........

You may find these links an interesting read:

Inaccessability of CAPTCHA (http://www.w3.org/TR/turingtest/)

pwntcha (http://sam.zoy.org/pwntcha/)

I found the first link much more explicit in terms. It is not a little off topic like the second one. All in all both are an interesting read as you said.

wow...i'm going to try this in my php site to prevent spammers...

How can use this code ???

The code and an example is in the very first post.

To make it more effective, since at the moment if a bot manages to read it each time it can just input all the characters get through, so the way I do it is use str_split($captcha_code, 1) so the code is split into 6 individual chunks, 1 character each. Then you can use a random number generator and depending on the outcome it can ask the user for 5 of the 6 characters, from 11111 to 66666 therefore the human can follow instructions as to which characters to insert. The bot will have a 1 in ~3'075 chance to get it right. If you have two codes on the same image, then the bot has 1 in 6'150 chance, etc...

Sam

Dear all,

I am still learning the PHP basic and came across this Captcha thread which i intend to implement into my site. How do i get about running this source code on the first post?

CAD










privacy (GDPR)