Important alert: (current site time 7/15/2013 9:43:48 AM EDT)
 

article

^ An Image Verification Tutorial

Email
Submitted on: 9/10/2002 9:35:29 PM
By: Darryl Porter 
Level: Beginner
User Rating: By 71 Users
Compatibility: PHP 4.0
Views: 129443
author picture
(About the author)
 
     Ever logged onto Yahoo! or here on Planet Source Code and have run across the verification image containing numbers and leters that you must plug into a form for verification? Learn to do it.

 
 
Terms of Agreement:   
By using this article, you agree to the following terms...   
  1. You may use this article in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
  2. You MAY NOT redistribute this article (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.   
  3. You may link to this article from another website, but ONLY if it is not wrapped in a frame. 
  4. You will abide by any additional copyright restrictions which the author may have placed in the article or article's description.
				


Image Verification Tutorial

I'm sure many of you have logged on to Yahoo!, eBay or even here on Planet Source Code and have run across the verification image containing numbers and letters that you must plug into an input box for verification. And maybe you thought, "What the heck is this for?" or "I wish I knew how to do that."
You wanna know--then I will show you how.

A script like this is usually used for further security of the user's information--or, like on Planet Source Code, so that "unscrupulous people" cannot use "HTTP Post code in their submissions to trick people into unknowingly voting for them."

Okay, enough talk--let's get started.

First, I assume that you have PHP 4 with the GD library already installed. Also, we will use session functions in this code to pass a varaible from one page to the next.

To create our image, we need to send a header telling the connection that we are about to send an image, we do that with the header function:
--------------------------------------------

 /*Send header*/
Header("Content-Type: image/png");

--------------------------------------------
We are going to be working with png images in this tutorial. But if you want to use "jpeg", just plug it in where "png" is in the header. (You can also call a "gif" image, but because of all the money stuff, most servers don't support it.)

I know your dying to get started building images, but first, we need to get a little more prep work out the way. So, let's put those session functions to work.
---------------------------------------------

/* initialize a session. */
session_start();

/*We'll set this variable later.*/
$new_string;

/*register the session variable. */
session_register('new_string');

-------------------------------------------------
All we did above was start a new session with the session start function. We will call this session on a different page that we will create later. Second, we created a variable called new_string that we will give a value to later. Lastly, we called the session register function: this function takes the variable we created as an argument minus the "$" sign, also, you must put it inside single quotes only. (An argument refers to the single or comma separated information inside the parenthesis of a function.)

With that out the way, we can now begin to create our image. We start this process by calling the create image function, which does exactly what it says: Creates an image.
---------------------------------------------

/* set up image*/
/*The first number is the width and the second is the height*/

$im = ImageCreate(200, 40);  

----------------------------------------------
I set the image Create() function to the variable $im. The variable $im will be our pointer to the image we just created for the rest of the tutorial. The image Create function take only two arguments and the arguments can only be integers (numbers). The first argument is the width of the image in pixels, the second, you guessed it, is the height.

Let's give our image some color.
----------------------------------------------

/*creates two variable to store color*/
$white = ImageColorAllocate($im, 255, 255, 255);
$black = ImageColorAllocate($im, 0, 0, 0);

----------------------------------------------
I called the Image Color Allocate function twice. The first time is to set the color for white, the second to set the color for black. The function take 4 arguments: The image pointer variable $im, and the RGB (red, green, blue) components that are separated by commas.
(255, 255, 255, is the code for white, while 0, 0, 0, is the code for black. You can play with the numbers to produce any color you want.)
At this point we have a png image and two colors. Now we will create a random string generator to place as the verification code inside the image. I won't discuss how the random generator code works, but will only lay out the code with comments.
------------------------------------------------

/*random string generator.*/
/*The seed for the random number*/

srand((double)microtime()*1000000);

/*Runs the string through the md5 function--which is a function that encrypts a string, changing it into a 32 character string composed of numbers and lowercase letters*/

$string = md5(rand(0,9999));

/*Creates the new string. The first number is the point in the 32 character string where we will pull our string from. In other words, PHP will count (beginning at 0) 17 characters into the string. The 18th character in will be our beginning point (remember, PHP starts counting from 0). From there, PHP counts 5 characters from that point, and thus, we get our five character string. The second number is the length of our string--changing this number will give us different string lengths.*/
$new_string = substr($string, 17, 5);
-------------------------------------------------

Moving on--Now let's fill the image with color.
-------------------------------------------------

 /*fill image with black*/
ImageFill($im, 0, 0, $black);

---------------------------------------------------
The Image Fill function is called first. It takes 4 arguments: Again we add the image pointer variable $im, the second and third are x, y coordinates in our image, 0, 0, being at the top left corner. Our image size is 200x40, therefore, the bottom right corner would be 200, 40. The fourth argument tell us with what color to fill the image with: In our case it is black.

Now, let's add the string we just created to our image.
----------------------------------------------------

 /*write string at coordinates (70,10) in the color white. (70, 10) puts the string almost in the middle of the image.*/
ImageString($im, 4, 70, 10, $new_string, $white);

-----------------------------------------------------
We have yet another function: Image String, and yes, it adds a string to our image. It takes six arguments. The first is the image pointer variable, the second argument can be any number from 1 to 5,(which calls for one of the built in fonts). The next two arguments are the coordinates, first the x (width) then the y (height). This is for the placement of our string. The next argument calls for the string variable. In our case it is $new_string. The last argument is the variable containing the color, which is $white.

We end the image build by outputting our image using the code below:
-----------------------------------------------------

 /*output to browser*/
ImagePNG($im, "verify.png");
ImageDestroy($im);

------------------------------------------------------
We have the imagePNG function with two arguments: again, like always the image pointer, the second argument names the image "verify.png" and saves the image in the current directory. If you want the image in a different directory, proceed "verify.png" with the path to the directory.

Hey, we're through building the image.

Finally, input the Image Destroy function, it has one argument: the pointer variable. Destroying the image frees up server memory. Your server administrator will like you for this. Your code should look like this:
-----------------------------------------------------

<?php
 /*header*/
Header("Content-Type: image/png");

/* initialize a session. */

session_start();

/*We'll set this variable later.*/
$new_string;

/*register the session variable. */
session_register('new_string');

/*You will need these two lines below.*/
echo "<html><head><title>Verification</title></head>";
echo "<body>";

/* set up image, the first number is the width and the second is the height*/
$im = ImageCreate(200, 40);

/*creates two variables to store color*/
$white = ImageColorAllocate($im, 255, 255, 255);
$black = ImageColorAllocate($im, 0, 0, 0);

/*random string generator.*/
/*The seed for the random number*/

srand((double)microtime()*1000000);

/*Runs the string through the md5 function*/
$string = md5(rand(0,9999));

/*creates the new string. */
$new_string = substr($string, 17, 5);

 /*fill image with black*/
ImageFill($im, 0, 0, $black);

 /*writes string */
ImageString($im, 4, 96, 19, $new_string, $white);

/* output to browser*/
ImagePNG($im, "verify.png");
ImageDestroy($im);
?>
---------------------------------------------------
Now place a form input box below our image (see the code below), and ask the user to input the string they see in the image in the text box. Append this code to the bottom of the code above, before the "?>."
---------------------------------------------------

/*I plugged our image in like I would any other image.*/
echo "<img src=\"verify.png\">";
echo "<br><br>";
echo "Type the code you see in the image in the box below. (case sensitive)";
echo " <form action=\"formhandler.php\" method=post>";
echo "<input name=\"random\" type=\"text\" value=\"\">";
echo "<input type=\"submit\">";
echo "</form>";
echo "</body>";
echo "</html>";

---------------------------------------------------
With that done, we must now create a new file and name it formhandler.php. We will put the code below into it.
---------------------------------------------------

<?php
/*This starts the session that we created on the last page*/
session_start();

/*This trims the random variable of any white space that the user may have unknowingly put in.*/
$random = trim($random);

/*Below is a conditional statement: In English it reads, if the string that the user put into the text box is equal to what is in the image then print to the screen, "You are verified."  If they are not equal it tells the user to go back and try again.*/

/*We can use the variable $new_string because we registered it into our session on the last page, it retains its value that it had on the first page.*/
if ($new_string == $random){
echo "You are verified";
}
else{
echo "Please go back and get verified.";
}
?>

There you are. Try it out. IF you have any trouble send me an e-mail. And that's that.

Thanks to comments left below, this article has been updated by the Author.
Please Rate this Tutorial!!!

 


Other 2 submission(s) by this author

 


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this article (in the Beginner category)?
(The article with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments

9/11/2002 2:19:51 AMMehdi Hanbali

Bravo, EXCELLENT code. I haven't seen something this useful in a long time. Good work, totally worth a perfect score.
(If this comment was disrespectful, please report it.)

 
9/11/2002 10:51:06 AM

I really liked the code. Very impressive. I do mention one thing though that will improve the code a little bit. If I understand the code correctly, you are passing the verification code back to the form as a form element, a hidden one, but a form element no less. This would allow the user to write a program which looks at the HTML code and type in the verification code. This would defeat the purpose. To make it even stronger, it would be best to remove this from the code and put it in a session, or a hash that you load each time, but something that would keep it invisible from the user.

Thanks for sharing the code. It was really good.
(If this comment was disrespectful, please report it.)

 
9/11/2002 11:34:41 AM

Very nice indeed.
(If this comment was disrespectful, please report it.)

 
9/15/2002 7:26:17 PM

This is horrible... absolutely worthless! just kidding, couldn't complain if I had to. Nice code!
(If this comment was disrespectful, please report it.)

 
9/15/2002 10:32:16 PMDarryl Porter

I had to pick my lip off the floor before I could continue to read--Thanks for the feedback--
(If this comment was disrespectful, please report it.)

 
9/18/2002 5:04:33 AMdavid.emmo

very nice! thanks! not sure i'd use it in the way you've described but very useful all the same!
(If this comment was disrespectful, please report it.)

 
9/18/2002 5:08:48 AMdavid.emmo

oooh...and when i rated it, guess what i had to do...? :)
(If this comment was disrespectful, please report it.)

 
10/6/2002 2:55:45 PMAlex Graf

Hi. I looked through your code again. Well, true, it only differs from mine in this minor detail: You use one font for writing the Text. I use 5 different ones instead. So, one could use an OCR program to read the string. But since this is quite unlikely, well.... um. I wrote in mail that i´m sorry, if it looked like i was stealing your code. I didn´t intend to. I think we only had the same idea. Please forgive me. :(

Alex
(If this comment was disrespectful, please report it.)

 
11/20/2002 2:46:12 AM

Great php code..
(If this comment was disrespectful, please report it.)

 
4/6/2003 9:53:50 PMJT Squirrel

kool code. its very nice
(If this comment was disrespectful, please report it.)

 
4/10/2003 7:05:51 AM

Thanks alot for the code, it was very helpful. However, I don't understand why you're sending the content type as an image, if the script is a page with a form, image, and text. I removed Header(
(If this comment was disrespectful, please report it.)

 
4/10/2003 2:46:05 PMDarryl Porter

I use the header(); function to send the image because more than anything this article is about teaching people to use PHP to create images and some of the basic of that subject--I through it in to be thorough.
(If this comment was disrespectful, please report it.)

 
5/17/2003 4:24:46 PM

very nice code ... well worth using and a 5 star rating.
(If this comment was disrespectful, please report it.)

 
7/7/2003 10:55:13 PM

great program man!
(If this comment was disrespectful, please report it.)

 
7/16/2003 8:36:48 AM

Nice code ...
(If this comment was disrespectful, please report it.)

 
8/16/2003 11:08:25 AM

Very useful!
(If this comment was disrespectful, please report it.)

 
8/25/2003 2:30:35 PM

I don't understand -- what keeps a 'bot from reading the session variable that it gets and entering that automatically? It pretty much defeats the purpose all together. But granted, this program does create a random image.
(If this comment was disrespectful, please report it.)

 
8/25/2003 4:32:44 PMDarryl Porter

Session are stored server side and cannot be read outside the scope of the site. The bot would have to be located on the same server on which the script resides and in the same account in order to read the session variables.
(If this comment was disrespectful, please report it.)

 
9/4/2003 3:34:21 PM

I need to generate banners on the fly this code will come in so handy, but what if I want to use a font other then the pre-defined 5?
(If this comment was disrespectful, please report it.)

 
11/8/2003 5:22:25 AM

Really Cool! Thanks!
(If this comment was disrespectful, please report it.)

 
11/28/2003 11:59:35 AMJamin

Very nice code. I had some problems to start with, but that was because I hadn't told PHP to auto start the sessions in the php.ini file.
(If this comment was disrespectful, please report it.)

 
2/12/2004 11:08:21 AM

Hi, I liked the code very much. However, I was wondering if someone else has noticed this. If this were to be used on a high traffic site where people could be generating the verify.png image at the exact same time it will overwrite the image that should be displayed for the person who called it first.

Anyone know away around this?
(If this comment was disrespectful, please report it.)

 
2/12/2004 10:10:08 PMDarryl Porter

This code is a tutorial to help show some of the functions used in the GD library. It is not to be used unless it undergoes some modifications.

Also, when I worte this, PHP was still in early version 4, this code will not stand under the latest version.
(If this comment was disrespectful, please report it.)

 
5/8/2004 8:46:40 AMNaif

Wow !!!
(If this comment was disrespectful, please report it.)

 
7/28/2004 4:26:23 PMPHP Duo

Thanks a ton for sharing this :) Could you please tell me where to download the GD library and how to install it on the server ?
(If this comment was disrespectful, please report it.)

 
7/28/2004 4:45:01 PMPHP Duo

Ok ! I felt it I should contribute a bit than ask more. Here is the link to the gd library website: http://www.boutell.com/gd

If you are using an older version than 4.3.x of php, go here to patchup: http://www.boutell.com/gd/phppatch.html

If you already have a version 4.3.x or greater running, it's so easy to do it ! You just need to uncomment something and change the path of extensions. Read here: http://www.boutell.com/gd/faq.html

I hope that helps. I just got it running :)

--
Swaroop :D
(If this comment was disrespectful, please report it.)

 
8/1/2004 5:36:02 AMAlpha Binary

Nice, but why on earth did you put the Header("Content-Type: image/png"); in if you are going to return a html page?

BTW how can i use a custom font other than the default four fonts?
(If this comment was disrespectful, please report it.)

 
8/17/2004 8:04:24 AM

If I wanted to be sent to forwarded to another site after verification , how would i do it, otherwise its a cool code.
I like it

(If this comment was disrespectful, please report it.)

 
9/22/2004 4:16:07 PMversatilia

Interesting... http://www.phpnoise.com/tutorials/1/1
(If this comment was disrespectful, please report it.)

 
11/1/2004 5:57:05 PM

Kinda pointless...your image can EASILY be read by any decnet OCR engine. The whole point of the image verification is to defeat OCR technology. All you have shown is that you can generate and image and add text to it. 101 stuff.
(If this comment was disrespectful, please report it.)

 
12/22/2004 6:27:39 AM

I need help.
i have problem with this script :(.
pls explain why i got error:
http://www.nastygirl.ws/1/
i talk with hosting provider but they silly and ask me what concretelly not work. :(
(If this comment was disrespectful, please report it.)

 
4/2/2005 9:52:28 AM

i did a similar php thing, i don't know how i found this ... it's just a test script, but works, and is very robust.

http://higginsforpresident.net/projects/tacs/

click 'demo' and give it a whirl. source and all stuff is overly commented for the novice php coder.
(If this comment was disrespectful, please report it.)

 
4/24/2005 7:57:10 AMSebring

how about an online demo?
(If this comment was disrespectful, please report it.)

 
4/29/2005 1:30:18 PM

yes! online demo would be very cool.
see my attempt at a PHP captcha at http://www.puremango.co.uk/cm_freecap_113.php
(If this comment was disrespectful, please report it.)

 
4/29/2005 1:31:17 PM

ack! that's http://www.puremango.co.uk/cm_freecap_113.php (url above was screwed up)
(If this comment was disrespectful, please report it.)

 
6/30/2005 9:54:39 AM

quote: I was wondering if someone else has noticed this. If this were to be used on a high traffic site where people could be generating the verify.png image at the exact same time it will overwrite the image that should be displayed for the person who called it first. Anyone know away around this?

The usual way around this problem is to use the php file as if it *was* an image file, rather than having it create an image file. I can't use the image functions on my current server, but as I recall it's not very hard to do.
(If this comment was disrespectful, please report it.)

 
6/30/2005 9:58:51 AM

My bad. I just had another look, and it seems the code is already done so it won't have problems with high traffic. Ignore my previous message. Sorry.
(If this comment was disrespectful, please report it.)

 
8/26/2005 4:25:52 AMsachin

This works fine in IE 6.
But when browsed in FireFox, the following is the error:
"The image "http://localhost/test.com/image-form.php” cannot be displayed, because it contains errors."

Could you fix it plz.

(If this comment was disrespectful, please report it.)

 
8/26/2005 4:28:12 AMsachin

This works fine in IE 6.
But when browsed in FireFox, the following is the error:
The image http://localhost/test.com/image-form.php” cannot be displayed, because it contains errors.

Could you fix it plz.

(If this comment was disrespectful, please report it.)

 
10/17/2005 5:18:11 AMviajero-loco

It's a great solution! I have just implemented it after being spammed to death in my guestbook. There is however one extra condition I recommend to add:

if ($IMGVER_EnteredText == $IMGVER_RandomText AND $IMGVER_EnteredText!="")

what it checks is if $IMGVER_EnteredText does not equal ZERO. This is important because if spammers found your verificate.php file they don't have to input any code as the session is not started (i.e. $IMGVER_EnteredText = 0). This will prevent from getting the spam even with the picture being generated.
Good luck!

http://www.southamerica-photo.com/
(If this comment was disrespectful, please report it.)

 
10/30/2005 5:16:23 PMKarl

It did not work in FireFox. Have tried over and over but can't use it before this error are fixed:

The image http://my.localhost.no/phpstuff/verify.php” cannot be displayed, because it contains errors.

OS: W2k
Software: IIS 5.0
PHP 5.0.5 Win32

gd
GD Support enabled
GD Version bundled (2.0.28 compatible)
FreeType Support enabled
FreeType Linkage with freetype
FreeType Version 2.1.9
T1Lib Support enabled
GIF Read Support enabled
GIF Create Support enabled
JPG Support enabled
PNG Support enabled
WBMP Support enabled
XBM Support enabled


(If this comment was disrespectful, please report it.)

 
11/3/2005 12:13:56 AMDavid

Great article, the issue I had and form verification going back to login form, the string code would change, but the .png image would contain the same code until you did a manual refresh of the browser.

I am sure there is a way to do it with your code, but I found this and am using it for my verification.

http://www.clixnetwork.com/articles/22/php-image-code
(If this comment was disrespectful, please report it.)

 
1/4/2006 1:18:21 PMGreg

WORKS IN FIREFOX!

To get this to work with Firefox, I commented out the following line:
Header("Content-Type: image/png");

It now works perfectly in both Firefox and IE!
(If this comment was disrespectful, please report it.)

 
1/19/2006 4:54:19 PMDesertdog

Hi, the code was very useful. Thank you very much!.
I added some code that might be useful (randomly allocated each character, and added dots and lines for “noise” using IMAGESETPIXEL and IMAGELINE functions).
Also generate the image name randomly and delete it using UNLINK() on the second page. Only 1000 chars allowed here, I can send you the code by mail.

(If this comment was disrespectful, please report it.)

 
1/19/2006 4:55:13 PMDesertdog

Hi, the code was very useful. Thank you very much!.
I added some code that might be useful (randomly allocated each character, and added dots and lines for noise” effect using IMAGESETPIXEL and IMAGELINE functions).
Also generate the image name randomly and delete it using UNLINK() on the second page. Only 1000 chars allowed here, I can send you the code by mail.

(If this comment was disrespectful, please report it.)

 
2/1/2006 6:04:06 PMJulien CROUZET

To have an animated picture instead, have a look here => http://blog.theoconcept.com/static/distortion/distortion-source.php

This give this result :
http://blog.theoconcept.com/index.php/2006/01/27/3-un-peu-tordu-comme-idee
(If this comment was disrespectful, please report it.)

 
3/19/2006 1:20:42 PMMike

Hi, noobie here!Will this code work on Frontpage web servers?
Thanks
(If this comment was disrespectful, please report it.)

 
4/24/2006 12:24:24 PMSander

Hi,
Do I need to put all the code in formhandler.php or do I have to create 2 .php files in order to get this working?
(If this comment was disrespectful, please report it.)

 
5/11/2006 1:19:29 PMRizwan Abbasi

What can i say about this code? I don't have words to praise this code and especially the author of this code. I SALUTE the author.
All the best.
(If this comment was disrespectful, please report it.)

 
5/26/2006 8:42:18 AMKal

Hi there, i've just been using the image verification snippet above and doesn't seem to work, i keep getting the following error, could please help me.

Warning: imagepng() [function.imagepng]: Unable to open 'verify.png' for writing in /var/www/html/spam/test1.php on line 41

(If this comment was disrespectful, please report it.)

 
6/3/2006 4:26:01 AMleny

Kal, you probably use linux as your server. You have to have the proper rights for writing into /var/www/html/. I think (I am not experienced in Linux) your problem can be solved if you are logged in as root and you do the following command:

chmod 777 /var/www/html/

I think it should solve the problem, but feel free to correct me!
(If this comment was disrespectful, please report it.)

 
9/1/2006 10:59:34 AMmark

Hi,
I keep getting a parse error when I try the above code:
Parse error: parse error, unexpected T_VARIABLE in /homepages/41/d171489552/htdocs/image_verification/form.php on line 20

It's strange b/c all I did was take your exact code, but changed the png to be a jpeg.

Any ideas?
(If this comment was disrespectful, please report it.)

 
9/10/2006 12:18:52 AMEnrico chavez

This a very good code thank you!
(If this comment was disrespectful, please report it.)

 
9/27/2006 3:13:15 AMneo

thank its helping me
(If this comment was disrespectful, please report it.)

 
10/13/2006 2:33:23 AMJulius

Interesting!
Keep Going!
(If this comment was disrespectful, please report it.)

 
10/18/2006 1:48:41 PMtreehousetim

Great article!

I recently wrote a php captcha that uses no images. It uses ASCII art fonts to display the code.

Take a look at the online demo:
http://www.thephppro.com/products/captcha/
(If this comment was disrespectful, please report it.)

 
2/21/2007 8:12:18 AMMike

Very impressive. Works beautifully in IE7 but in Firefox 2 I get the following error
The image "http://www.xxx.com/verify.php” cannot be displayed, because it contains errors.

Any ideas??
(If this comment was disrespectful, please report it.)

 
5/14/2007 4:32:25 AMkris

good
(If this comment was disrespectful, please report it.)

 
8/4/2007 11:04:05 PMKorab Hoxha

woww nice code
(If this comment was disrespectful, please report it.)

 
8/30/2007 5:09:59 AMGaurav

Hi,

Firstly it is an excellent tutorial. But there is a small bug in the code. When you load the script for the first time you need to refresh the page again before you enter the image code. Or else even if you enter the right code it still asks you to go back and get verified. Once you do go back and refresh the page, all the other form data is lost. Hence is there any solution for this. I have a working example of what I am saying at ths location. http://www.effectwave.com/test/image-form.php

Once you go here, try entering the image code and see what happens.
(If this comment was disrespectful, please report it.)

 
12/27/2007 1:35:21 AMtrananhtuan

thank!
(If this comment was disrespectful, please report it.)

 
1/6/2008 9:58:35 PMtrananhtuan

hi
i am from vietnamese
thank very much
(If this comment was disrespectful, please report it.)

 
3/15/2010 4:20:56 AMFaiz Muhammad Khan

wow its good.
(If this comment was disrespectful, please report it.)

 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular article, please click here instead.)
 

To post feedback, first please login.