Jump to content
xisto Community
rvalkass

A Simple Php Captcha - Image Validation

Recommended Posts

Thank you very much

A Simple Php Captcha - Image Validation

 

Thank you very much for this wonderful tutorial. I really needed something like this, EASY TO UNDERSTAND.

 

-feedback by adrian

Share this post


Link to post
Share on other sites

Listen, guys! How can I plug this captcha script into two things.1. Registration Form2. Login Form.And I would like that it will be kind of an answer, for instance, 56+2={...}.A user who wanna register, has to type an answer in field box.

Share this post


Link to post
Share on other sites

This Captcha script just works with an image designed to confuse the edge detection software used by spammers. The system of typing an answer to a math problem is also a good idea, but requires a slightly different approach. However, if you are interested, I might write a tutorial for that, and a few other ideas for Captchas.

Share this post


Link to post
Share on other sites

So, how can I integrate it with my registration project

If you would have bothered to read QuickSilva's post then you wouldn't be asking that. He laid out some excellent php code you can use. And perhaps if you can't do things like image CAPTCHA's even when they are so politely handed over to you on a silver platter, perhaps you shouldn't be doing projects as complex as you are doing.

Share this post


Link to post
Share on other sites

Hmm...

A Simple Php Captcha - Image Validation

 

Your version is readable, but it will be no problem for robots to crack this, since the font is always white, and has same parameters, who cares the background changes... So this is one of the worst captchas :( sorry

 

-reply by Martin Zvarik

Share this post


Link to post
Share on other sites
Thank You!A Simple Php Captcha - Image Validation

I am author of the ASP Inline Calendar so my coding basis is in ASP. I am working on a script that is PHP based for another website, so this is a new language to me. This tutorial provided excellent information and was very easy to implement. Keep up the good work, it's important that we have people like yourself willing to take the time to educate others.

-reply by AaronOutpost.Com

Share this post


Link to post
Share on other sites

Cool, I always wanted to know how they work. Even tough there are plenty of pre-made CAPTCHAs is awesome to know this. Thank you for sharing this mate.Cheers!

Share this post


Link to post
Share on other sites

OK, I recently had the need to create a PHP CAPTCHA system for a friend, and I am sharing this as a tutorial with the good people here at Xisto. I am sure you have all seen a CAPTCHA before (although you may not have known what it was called). They are the little codes you often have to enter when you register with a site, to make sure you are a person and not an automated script. Some common examples look something like this:

 

Posted Image

 

My system doesn't really do anything as fancy, but I think that it is slightly more readable that some of those that get generated. Everyone wants to see the final product before they start, so here are a few examples of what this script generates:

 

Posted Image

 

OK, lets get started. Open up your favourite text/code editor (Kate, Notepad, Dreamweaver...) and you're ready.

 

First, we need to tell the browser what we are going to ouput at the end of this, seeing as it won't be standard HTML.

 

<?php Header ("(anti-spam-(anti-spam-(anti-spam-content-type:))) image/png");

Simple enough. We are creating an image. Its a PNG. Now we need some randomness in our process. I have used 2 random numbers here, one as a string to be encoded with MD5, and the other will be used to cut our 32 character MD5 output into a 8 character code.

 

$enc_num = rand(0, 9999); //This number will be encrypted $key_num = rand(0, 24); //This is used to choose which bit of our string to use in the image

Our first number is anywhere between 0 and 9999. It doesn't really matter what the range is, its just used to give MD5 something to encrypt. Our second number has to be specifically in the range of 0 to 24. Why? MD5 creates a 32 character string, of which we only need 8 characters. To add some extra randomness, this number chooses our starting character. It can't go above 24 (32-8) or we get less than 8 characters. So, to generate our string:

 

$hash_string = substr(md5($enc_num), $key_num, 8);

Now we can start on the actual image. Here is where you get some customisation. If you look at my example above, I have used 3 background images which I premade for my script to use. You can use as many or as few as you like, just add the file names to this array, and add that to your code so far. Make sure they are in the PNG format! My array looks like this (with the images in the same directory as the script):

 

$bgs = array("lipsum.png", "fibres.png", "rainbow.png");

Designing the backgrounds with an image editor allows you to make sure that the text will be readable on them. All of mine allow the text to be easily seen to a human, but not so easily to a computer. Now of course, we need to pick one of these images to use as the basis for our CAPTCHA. There is a useful function called array_rand which will select one item from an array at random. Bingo!

 

$background = array_rand($bgs, 1);

The GD library (available with all good hosts, such as Xisto) allows us to create images to output, and we will use this now. First, we create an image from a premade PNG background with this oh-so-inventively named function:

 

$img_handle = imagecreatefrompng($bgs[$background]);

Next, we set the text colour and size. I have used a white colour as it shows up well on all of my backgrounds. Try changing the values if white doesn't look good for you.

 

$text_colour = imagecolorallocate($img_handle, 255, 255, 255); $font_size = 5;

I've also done some fancy central alignment on the text, despite the fact all my images have the same dimensions :D It allows for expansion, and you can design images to fit your site design.

 

$size_array = getimagesize($bgs[$background]); $img_w = $size_array[0]; $img_h = $size_array[1];

That simply gets the width and height of the background in pixels. Now we do some maths to find where the top left of the text should go, compensating for the width of the text.

 

$horiz = round(($img_w/2)-((strlen($hash_string)*imagefontwidth(5))/2), 1); $vert = round(($img_h/2)-(imagefontheight($font_size)/2));

Lastly, we plug all this together. We add the text to the image, display it to the browser, then destroy the temporary file.

 

imagestring($img_handle, $font_size, $horiz, $vert, $hash_string, $text_colour); imagepng($img_handle); imagedestroy($img_handle); ?>

If you have any problems then feel free to ask away and I'll do my best. In the future I may add the functionality for a PHP-generated background, random colours, custom fonts, and to apply some warping to the text. My aim is to still keep it readable though.

 

I carried out a (very un-scientific) test using my scanner's OCR software and that was unable to read the text. I am sure that if someone was determined and bothered enough then they would be able to break it, but it adds that little extra layer of protection to prevent people submitting things over and over, or computers being used to creat hundreds of messages, accounts...

 

I have also attached the completed source code and my images here too. Feel free to use them, and if you do it would be nice to see how you are using it. Also, feel free to offer improvements and suggestions.

 

Demo: http://forums.xisto.com/no_longer_exists/

nice tutorial

i've tested it and its working fine...

but i still prefer using reCaptcha though... :D

Share this post


Link to post
Share on other sites
RE: CAPTCHA validationA Simple Php Captcha - Image Validation

I, too, have had the need to filter spam-bots from my site, and have done a small amount of research into solving some of the problems associated with this type of security. What follows is a small, but rather elegant (if I do say so myself) solution. But first, let's pose a scenario or two:

1.) On my site, I have 2 folks who are accessing the same page containing my CAPTCHA at the same time. Using a generic SESSION, User A loads his page first, and the CAPTCHA image script sets the CAP session variable to "FG3TD", while User B loads his page second, setting the CAP session variable to "GJ78K". Meanwhile, User A submits his page, with the correct CAP comparison code, but gets a failure, since the session variable was changed by User B. This is obviously unnacceptable.

2.) Also, as was previously mentioned,backgrounds of said images don't really do much to reduce the success rate of CAPTCHA cracking scripts, since one can just XOR out the majority of the background, making it much easier to crack the letters left behind. Especially if they're all the same size, position and color. So how do we fix this?

Ok, so here's what I came up with. It solves many of the problems discussed, giving us a CAPTCHA image that is harder to crack, while being VERY small, code-wise. A working example can be seen below:http://forums.xisto.com/no_longer_exists/

As you can see, it uses a non-standard font, which slows down the cracking process, and for added security, can also be randomized. Also, the positions, font size and angle are all randomized, again making it harder to crack. Plus, the "background" is completely randomized, in both placement and color. And all of this is accomplished in less than 40 lines of code!

And as far as the problem with different users changing the session variables, that's avoided by using uniquely named session names. The code follows:

<?php  ini_set ("session.Save_path", $_SERVER['DOCUMENT_ROOT'] . "/mySessions");  session_start();  session_name($_SERVER['REMOTE_HOST'] . "-captcha");  $myCryptBase = "AB0CDE1FG2HIJ3KL4MNO5PQ6RST7UV8WX9YZ";  $capString = "";  $image = imagecreatetruecolor(150, 60);  $white = imagecolorallocate ($image, 255, 255, 255);  $rndm = imagecolorallocate ($image, rand(64,192),  rand(64,192),  rand(64,192));  imagefill ($image, 0, 0, $white);  $fontName = "fonts/GILLIGAN.Ttf";  $myX = 15;  $myY = 30;  $angle = 0;  for ($x = 0; $x <=1000; $x++) {   $myX = rand(1,148);   $myY = rand(1,58);   imageline($image, $myX, $myY, $myX + rand(-5,5), $myY + rand(-5,5), $rndm);  }  for ($x = 0; $x <= 4; $x++) {   $dark = imagecolorallocate ($image, rand(5,128),rand(5,128),rand(5,128));   $capChar = substr($myCryptBase, rand(1,35), 1);   $capString .= $capChar;   $fs = rand (20, 26);   $myX = 15 + ($x * 28+ rand(-5,5));   $myY = rand($fs + 2,55);   $angle = rand(-30, 30);   ImageTTFText ($image,$fs, $angle, $myX, $myY, $dark, $fontName, $capChar);  }  $_SESSION["capString"] = $capString;  header ("Content-type: image/jpeg");  imagejpeg($image,"",95);  imagedestroy($image);?>

(It seems that I can't locate the tag used to encapsulate code snippets. I hope this works as planned)

-reply by Dave Morton

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.