A Generic CAPTCHA Image Tester
By Peter A. Bromberg, Ph.D.
Printer - Friendly Version

Peter Bromberg

A captcha (an acronym for " Completely Automated Public Turing test to tell Computers and Humans Apart") is a type of challenge-response test used in computing to determine whether or not the user is human. The term was coined in 2000 by Luis von Ahn , Manuel Blum , and Nicholas J. Hopper of Carnegie Mellon University , and John Langford of IBM . A common type of captcha requires that the user type the letters of a distorted and/or obscured word that appears on the screen.

Captchas are used to prevent bots from using various types of computing services. Applications include preventing bots from taking part in online polls, registering for free email accounts (which may then be used to send spam ), and, more recently, preventing bot-generated spam by requiring that the (unrecognized) sender successfully pass a captcha test before the email message is delivered.



By definition, captchas have the following characteristics:

  • They are completely automated . This avoids the necessity for human maintenance or intervention in the test, with obvious benefits in cost and reliability.
  • The algorithm used is made public . This is stipulated so as to require that breaking a captcha requires the solution of a hard problem in the field of artificial intelligence rather than just the discovery of the algorithm, which could be obtained through reverse engineering or other means.

There are several implementations of CAPTCHA - generating image classes in .NET, and rather than reinvent the wheel, I decided to use the class put out by "BrainJar" at codeproject.

What's unique here is my implementation - it's generic enough to use in a classic ASP page, or in an ASP.NET page, it does NOT require the use of Session State, and that's what makes it more useful. The key here is that we use an aspx page to generate the image, and we simply make our image tag's src property point to this page. In my implementation, the "code" that the image class generates is simply added to the querystring. However - in order to defeat "bots" and even human hackers, there is an encryption algorithm used before the image is generated. The result is that the string of numbers displayed in the CAPTCHA image is completely different than the numbers that were on the querystring!

Finally, when we check the user's form post to compare what they entered in the "Code" text field, we again apply this same encryption algorithm so that we are still comparing "apples to apples". Sweet! The key to being able to use this on any type of web page is that the algorithm to create the image tag's src property along with the special code on the querystring is created by about 5 simple lines of client-side Javascript:

function createCode(){
var temp="";
for(var i=0;i<5;i++)
{
temp+= Math.round(Math.random() * 8 );
}
document.all.theImg.src="JpegImage.aspx?code=" +temp;
document.all.Hidden1.value=temp;
}

OK, almost anyone can figure out what I am doing in the above code. Why am I generating a string of random digits no larger than eight? Well, because my "poor man's encryption algorithm" simply adds 1 to each digit, and that's the number put out by the image class. Notice also that I insert the value in a hidden form field at the same time. This will be used to compare to what the user typed into their validation textbox. That is, of course, after we reapply the encryption algorithm. By the way - if adding "1" to each digit of a number isn't strong enough for you, please feel free to implement Triple DES or whatever suits your fancy! The idea here is the concept - which you are free to use as you see fit.

Now let's see what happens with a POAP (plain old ASP page):

<%
if Request.Form("Submit")<> "" then
theCode=Request.Form("Hidden1")
for i= 1 to Len(theCode)
y = CInt( mid(theCode, i,1) +1)
newText=newText & Cstr(y )
next
if Request.Form("CodeNumberTextBox") = newText then
MessageLabel = "Correct!"
else
MessageLabel="UH OH!"
end if
end if
%>

<body onload="createCode();">
<h2>CaptchaImage Form Test</h2>
<p>&nbsp; <img id="theImg" src=""><br>
</p>
<form id="Default" method="post" action="Default.asp">
<p>
<strong>Enter the code shown above:</strong><br>
<input id="CodeNumberTextBox" name="CodeNumberTextBox" >
<input type=submit id="Submit " name="Submit" Text="Submit">
<INPUT id="Hidden1" type="hidden" name="Hidden1" >
</p>

<p> <input type=text id=MessageLabel name=MessageLabel value="<%=MessageLabel%>">
</form>

You can see above that my classic VBSCRIPT code checks to see if the form was submitted, gets the Hidden1 formfield, adds back the 1 to each digit, and then compares this number with the one typed in by the user from looking at the CAPTCHA image on the page. You can also see that my <BODY> tag runs the createCode() function (the javascript up above) to populate the querystring on the image tag's src property. When this is done, the image tag dutifully makes an HTTP request for the image. Of course, in a production page, you wouldn't just display a message - you would either process the form or tell the "Bot" to "BUGOFF"!

Now in the JpegImage.aspx page that receives this request, the code looks like so:

private void Page_Load(object sender, System.EventArgs e)
{
// Create a CAPTCHA image using the querystring "code"
string theText=Request.QueryString["code"].ToString();
string newText=String.Empty;

int y=0;
for(int i=0;i<theText.Length;i++){
y = Int32.Parse(theText.Substring(i,1)) +1;
newText+= y.ToString();
}
CaptchaImage ci = new CaptchaImage(newText, 200, 50, "Arial");
this.Response.Clear();
this.Response.ContentType = "image/jpeg";

// Write the image to the response stream in JPEG format.
ci.Image.Save(this.Response.OutputStream, ImageFormat.Jpeg);

// cleanup
ci.Dispose();
}

And that completes the "generic Captcha image" implementation! If you would like to try it out, go here.

 

Download the Example solution

 

Peter Bromberg is a C# MVP, MCP, and .NET consultant who has worked in the banking and financial industry for 20 years. He has architected and developed web - based corporate distributed application solutions since 1995, and focuses exclusively on the .NET Platform.