A Better CAPTCHA Control (Look Ma - NO IMAGE!)

Peter takes a previous concept and applies it to the real world of "Really Useful" applications - A Better CAPTCHA!

We live in the Age of the Internet. It's a technologically - driven era in society where information flows more freely, is easier to access and find, and has more influence on the speed of development of the totality of the experience of being human and living human lives, than at any time in known history.

Along with that freedom and flow of information comes SPAM -- Blog SPAM, newsgroup SPAM, email SPAM. And so the CAPTCHA (an initialism for "Completely Automated Public Turing test to tell Computers and Humans Apart", trademarked by Carnegie Mellon University) came into play. CAPTCHA is a type of of challenge-response test used in computing to determine whether or not the user is human. The most common form of CAPTCHA requires that the user correctly type in the characters shown on an image, usually an obscured sequence of letters or digits that appears on the screen.

Unfortunately, this image-based CAPTCHA technique, which has become almost ubiquitous on blogs, newsgroups, forums and any other form of Internet community publication, is severely flawed. In order to prevent BOTS (automated spam mechanisms) from performing OCR on the characters in the displayed image, the CAPTCHA characters are often so deliberately obscured by lines, text warp effects and other visual "noise" that even we, the real humans, cannot read them correctly. I have good vision, and six times out of ten, I get the required input for a CAPTCHA challenge wrong on the first try. Not only is this inefficient, it is damned frustrating and it really puts a dent in the user experience. I doubt that many will disagree with this statement.  Can you imagine the difficulty someone with impaired vision will have? Yes, I know, you will tell me that there are CAPTCHAs that use audio, and so on. That isn't the point.

It is not necessary to put up with this. While there have been numerous "experiments" in offering "different kinds" of CAPTCHA Tests - e.g., selecting the "prettiest girl" from a group of images, using "smart questions", etc. they haven't really taken hold, and we, the poor Internet Users, must suffer the slings and arrows of CAPTCHA Bipolar Disorder just to leave a comment on our buddy's Blog. Yecch! We can do better.

I have an idea that offers an interesting alternative. If images are so susceptible to being Optical Character Recognized by bots, why display an image at all? That's right, FORGET ABOUT IMAGES.

In an earlier article, I featured a class that would turn an image into carefully CSS styled photorealistic HTML. Why not just apply this same technique to a CAPTCHA image with random text, and convert it to HTML, and display that instead? We can dispense with the visual noise, since there is no longer any image to OCR! That means it will be very easy to read, and still accomplish the objective of easily proving the user is human. Bye bye, Mr. BOT -- you now have NOTHING to defeat; we've just chopped your legs off! Sure, you can grab the HTML, but the only way you could possibly find out what the characters are is to have a human render it and read it!  (Of course, some enterprising soul may come up with a scheme to "recognize" the HTML instead, but we will be one step ahead of them with unannounced innovations, so fear not!)

In actual fact, you "could" still OCR this. You would have to grab the HTML, render it, take a screen cap of it into an image, and then finally you could perform OCR on the image.  But, that's highly unlikely to happen anytime soon, if you just think about it.

So, here's  what I did in order to create this, which  is very simple:

1) I took the best of some other people's "pretty good" ASP.NET CAPTCHA image controls that were open source or freeware, and
2) I made a new control that still creates the image, but it runs it through my Image2Html class and returns the string of styled HTML that "looks just like" the original image, and displays that instead. Everything else works exactly the same.

The difference is that now that we aren't using images any longer, we don't need to obfuscate them to the point where the poor user has to go blind figuring out what the damned text is that they need to enter! In fact, we don't need to obfuscate them AT ALL. 

The typical "size" of an HTML version of an image is somewhere in the range of 67K - quite a manageable amount of HMTL and not much bigger than a lot of images that people put in web pages anyway. In addition, since it's inline HTML right in the page, it does not require a separate HTTP request from the browser to get the image.

Here is  my Image2Html class, in case you missed the original article:

using System;
using System.Text;
using System.IO;
using System.Web;
using System.Net;
using System.Drawing ;
namespace PAB.Web.Utils
{    
    public class Image2Html
    {
        private Image2Html()
        {            
        }

        public static string ConvertImage(Bitmap img, int scale)
        {
             
    
            Bitmap b = img;
            MemoryStream ms = new MemoryStream();
            StreamWriter SW = new StreamWriter(ms);
        
            SW.WriteLine("<style>pre{letter-spacing:-4px;word-spacing:-4px;line-height:2px}</style>");
            SW.WriteLine("<pre><b><font size='1pt'>");
            string s2 = "";
            for (int y = 0; y < b.Height; y += scale)
            {
                for (int x = 0; x < b.Width; x += scale)
                {
                    Color c = b.GetPixel(x, y);
                     s2 = c.Name.Substring(2);
                    SW.Write("<font color='#" + s2 + "'>");
                    SW.Write(((byte)c.ToArgb()) >> 7);
                    SW.Write("</font>");
                }
                SW.WriteLine();
            }

            SW.WriteLine("</font></b></pre>");
           
            SW.Close();
            SW = null;
            byte[] b2 = ms.ToArray();
            string s = System.Text.Encoding.ASCII.GetString(b2);
            return s;
        }
    }
}


Here is a simple screen cap illustrating one layout of the control:



The CAPTCHA numbers and letters you see, which are quite easy to read, are NOT an image- they are HTML.

And here is the full Visual Studio 2005 solution with the control and a sample web page, which I am putting in the public domain. The control also features a settable timeout to help defeat those "human bot shops". Zero for the timeout means "no timeout". Please feel free to modify it, change it, make it "your own" and help me get rid of those AWFUL Image - based CAPTCHAS! Thank you!

NOTE: Look at Christopher Lewis' comment below for a nice enhancement that cuts way down on the amount of generated HTML by only changing the pixel color if it is different from the previous one.

By Peter Bromberg   Popularity  (12122 Views)