Welcome to Dream.In.Code
Getting C# Help is Easy!

Join 118,588 C# Programmers for FREE! Ask your question and get quick answers from experts. There are 847 online right now! We've got more than 500 tutorials and 2,000 snippets. Join and find out why Dream.In.Code is the #1 programming help community on the internet! Registration is fast and FREE... Join Now!



Captcha Made Easy

 
Reply to this topicStart new topic

> Captcha Made Easy, creating a simple captcha

rgfirefly24
Group Icon



post 5 May, 2008 - 09:52 AM
Post #1


Ok, so you've created your asp.net site, but something is troubleing you. You want to be able to check to make sure the person behind the user creation is actually human. Well an easy way to do this is called CAPTCHA.

CAPTCHA stands for : Completely Automated Turing Test To Tell Computers and Humans Apart

now Using captcha is not fool proof. There are programs out there called OCR's. OCR stands for optical character recognition. Basically this means that it takes an image, removes background clutter(meaning small lines and background images), segments the image if possible and reads each character individually. Most OCR readers have a 30%-50% effectiveness.

To create a captcha you need to break it down into several steps.


before we begin the process i would like to point out that this site Simple Captcha with ASP.NET was where i went to in order to start out in creating a CAPTCHA. You will notice that the Structure of
my code and the code on that site are similar. The reason is only for functionality. The variable names have been changed and alot has been added to make it more secure.

step 1:
you will need to create all the variables and other items needed for the CAPTCHA. start off by making a Bitmap and defining the Graphics for it. you will need to declare at least 1 random number generator, but in the following example i declared 3 to make the CAPTCHA a bit more challenging.
CODE

                Bitmap captchabmp = new Bitmap(120,50);
        
                Graphics captchagraphic = Graphics.FromImage(captchabmp);
        
                captchagraphic.Clear(Color.Black);
        
                captchagraphic.TextRenderingHint = TextRenderingHint.AntiAlias;
        
                Font captchafont = new Font("Ariel", 24);
                Font captchafont2 = new Font("Ariel", 24);
                HatchBrush captchafont3 = new HatchBrush(HatchStyle.Shingle, Color.GhostWhite, Color.Gold);
        
                string captchastr = "";
        
                char[] captchaarray = new char[5];
        
                int x;
        
                Random rand = new Random();
                Random upperlower = new Random();
                Random captcha = new Random();
                
                int z;
                int y;
        string temp;

Now we have our variables declared and setup our bitmap to be filled. A few things i want to point out
CODE

HatchBrush captchafont3 = new HatchBrush(HatchStyle.Shingle, Color.GhostWhite, Color.Gold);

What this line does is it Breaks up the actual image into a multicolored image based of the HatchStyle. This will make it alot harder for OCR readers as
they typically look for a solid color.


once you have your variables declared its time to start building the actual captcha image. For this you will need to learn the hex codes for letters A-Z, a-z, and numbers 1-9 (i leave out zero because its too easy to get confused with the letter o)

after that you will declare 2 for loops to build the actual image along with a few if statements:
CODE

for (x = 0; x < 5; x++)
         {
             z = captcha.Next(0,3);
             if (z ==  1)
             {
                 captchaarray[x] = System.Convert.ToChar(rand.Next(65,90));
             }
             else
             {
                 captchaarray[x] = System.Convert.ToChar(rand.Next(49,57));
             }
         }


at this point you now have an array of 5 random numbers and letters. From here you will use the 2nd for loop to change the letter to either upper or lower case( i did not need to parse out numbers as they are uneffected by this for loop)
CODE

        for (x = 0; x < 5; x++)
                {
                    y = upperlower.Next(0,99);
                    if (y >= 0 || y < 50)
                    {
                        temp = (captchaarray[x].ToString());
                        temp = temp.ToLower();
                        randomStr += temp.ToString();
                    }
                    else
                    {
                        temp = (captchaarray[x].ToString());
                        temp = temp.ToUpper();
                        randomStr += temp.ToString();
                    }
                }



now that you've got your Captcha array built and placed into a single string instead of an array its time to place it into the session for comparison in your actual program.
CODE

  /* this adds the string to the Session variable to be called upon in your main code. */

        Session.Add("captchastr", captchastr);


now it is time to Build up the actual image that will be displayed to the user. I have removed a good portion of this code for redundancy reasons.
CODE

String backgroundstring = "-OCR-";/* this will be used as a way to merge the image letters/numbers to make it hard for an OCR reader to segment*/


        captchagraphic.DrawString(backgroundstring, captchafont2, Brushes.Gold, 0, 3);// adds the backgroundstring to the image
        captchagraphic.DrawLine(new Pen(Brushes.Red), 1, 0, 1, 50);//these lines create the checkered background
        captchagraphic.DrawLine(new Pen(Brushes.Red), 5, 0, 5, 50);
        captchagraphic.DrawLine(new Pen(Brushes.Red), 10, 0, 10, 50);
        captchagraphic.DrawLine(new Pen(Brushes.Red), 15, 0, 15, 50);
        captchagraphic.DrawLine(new Pen(Brushes.Red), 20, 0, 20, 50);
        captchagraphic.DrawLine(new Pen(Brushes.Red), 25, 0, 25, 50);
        captchagraphic.DrawString(captchastr, captchafont, captchafont3, 3, 3);//adds the string we created to the image
    captchagraphic.DrawLine(new Pen(Brushes.Olive), 0, 20, 100, 20);//these next 3 lines create the "strike-through" effect
    captchagraphic.DrawLine(new Pen(Brushes.Azure), 0, 0, 100, 50);
        captchagraphic.DrawLine(new Pen(Brushes.Blue), 0, 50, 100, 0);


from here its time to Set the type of file you want it to be, and output it in that format. Also a good idea to dispose of your items so
future changes can be made with out worry.
CODE

Response.ContentType = "image/GIF";

         captchabmp.Save(Response.OutputStream, ImageFormat.Gif);

         captchafont.Dispose();
         captchafont2.Dispose();


         captchagraphic.Dispose();

        captchabmp.Dispose();


awsome now you have your Captcha image built.

Attached Image

Now remember i told you about segmentation.
OCR readers attempt to "break-up" an image into different sections based on where it interprets one letter starts and ends.
By adding the background word, and the "strike-through" effect i am attempting to block an OCR readers ability to segment my image.


now lets look at the code you need to place in your actual .aspx page

The actual code is only one line. Why? simply because we store the CAPTCHA letter/number combination in a Session variable. so in your button click event put this in before any actual code

CODE

if (Page.IsValid && (txtCaptcha.Text.ToString() == Session["captchastr"].ToString()))
{
}


now there are other ways of going about securing your site. You can use the AJAX toolkit no bot control which will deny any IP that hits the submit button in too short of time, or use another form of CAPTCHA your current choices are: MAPTCHA, CAPTCHA KittenAuth, Microsoft's "Asirra", and 3-D captcha

I hope this tutorial will get you well on your way to basic site security and user authentication. Later i will be posting tutorials on the NoBot control.

This post has been edited by skyhawk133: 5 May, 2008 - 10:28 AM
Go to the top of the page
+Quote Post


Register to Make This Ad Go Away!

mocker
**



post 5 May, 2008 - 02:13 PM
Post #2
good tutorial, but you may want to keep in mind that you want humans to be able to read it, not just make sure bots cannot. I have turned away in disgust from a number of websites that put so much obfuscation into their captcha that it looks like a mess and it blocks people as well as bots. In your sample image, having a background word makes it a complete pain in the ass to read, and unless I had to go to your site.. I wouldn't. Don't forget the users..
Go to the top of the page
+Quote Post

Nova Dragoon
Group Icon



post 5 May, 2008 - 02:16 PM
Post #3
IPB Image
Go to the top of the page
+Quote Post

ajaymatrix
Group Icon



post 5 May, 2008 - 06:44 PM
Post #4
good one..
the same thing can be done with PHP, I guess
Go to the top of the page
+Quote Post


Fast ReplyReply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 

Lo-Fi Version Time is now: 10/11/08 07:29PM

Live C# Help!

C# Tutorials

Reference Sheets

C# Snippets

Bye Bye Ads

Free DIC T-Shirt

T-Shirt Example

Related Sites

Monthly Drawing

Thumb Drive

Partners

Top Contributors

Top 10 Kudos This Month