search
Japanese Chinese Nederlands Espanol Italiano Deutsch Francais Twitter Rss Feeds
MicrosoftArticlesForumsFAQs
C# .NET
VB.NET
Visual Studio .NET
ADO.NET
Xml / Xslt
VB 6.0
.NET CF
GDI+
LINQ
Deployment
Security
FoxPro
Silverlight / WPF
Entity Framework
RIA Services

Web ProgrammingArticlesForumsFAQs
JavaScript
ASP
ASP.NET
Web Services

Non-MicrosoftArticlesForumsFAQs
NHibernate
Perl
PHP
Ruby
Java
Linux / Unix
Apple
Open Source

DatabasesArticlesForumsFAQs
SQL Server
Access
Oracle
MySQL
Other Databases

OfficeArticlesForumsFAQs
Excel
Word
Powerpoint
Outlook
Publisher
Money

Operating SystemsArticlesForumsFAQs
Windows 7
Windows Server
Windows Vista
Windows XP
Windows Update
MAC
Linux / UNIX

Server PlatformsArticlesForumsFAQs
BizTalk
Site Server
Exhange Server
IIS

Graphic DesignArticlesForumsFAQs
Macromedia Flash
Adobe PhotoShop
Expression Blend
Expression Design
Expression Web

OtherArticlesForumsFAQs
Subversion / CVS
Ask Dr. Dotnetsky
Active Directory
Networking
Uninstall Virus
Job Openings
Product Reviews
Search Engines
Resumes

 

An Ultra-Simple Sum of Numbers Captcha UserControl


By Peter Bromberg
Printer Friendly Version
View My Articles
12 Views
    

A very simple Sum-of-Numbers CAPTCHA UserControl that is easy to use and customize.


I don't know about you, but the proliferation of Captcha stuff on the web is anathema to me. It seems like they are rarely legible; in their effort to prevent bots and spam, practitioners have completely forgotten the first tenet of web presentation: usability! Usually it takes me two or three tries to get them right, it's annoying and frustrating as well. And I am talking about the "big guys" like Google, Yahoo and others who really should know better.

A Captcha control does not need to be fancy or complicated to be effective! As a case in point, Jeff Atwood ("CodingHorror") has had a fixed image with the word "Orange" as a Captcha on his blog for years, and he claims that it is hugely effective in preventing spam. You can see this at the bottom of the page linked in the previous sentence.

One type of Captcha is called "Sum of Numbers". It is very easy to implement as a UserControl, and it is very effective. That's what I use when a Captcha is called for. Nobody (other than the blind) will ever complain that they cannot read the numbers, and only the simplest of math is required for success (Hey, if you cannot add two random numbers in the range 1 through 10 then we have a different kind of problem!).

Let's dig into the code:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="SumCaptchaControl.ascx.cs" Inherits="SumCaptcha.SumCaptchaControl" %>
<style>
      .Yellowborder
       { 
          BORDER-RIGHT: #ffcc00 1px solid; BORDER-TOP: #ffcc00 1px solid;
          FONT-WEIGHT: normal; FONT-SIZE: 11px; BORDER-LEFT: #ffcc00 1px solid;
          COLOR: #000000; BORDER-BOTTOM: #ffcc00 1px solid;
          FONT-FAMILY: Verdana, Helvetica, sans-serif;
          BACKGROUND-COLOR: white;  overflow:hidden;
          width:350px;       
          text-align:center;  
       }
</style>
<div class="Yellowborder" width="350px" >
        <asp:Label ID="Label3" runat="server" Text="Ennter the sum of these numbers:"></asp:Label>
        <asp:Label ID="lblNum1" runat="server"></asp:Label>
        <asp:Label ID="Label4" runat="server" Text="+"></asp:Label>
        <asp:Label ID="lblNum2" runat="server"></asp:Label>        
        <asp:Label ID="Label5" runat="server" Text="="></asp:Label>
        <asp:TextBox ID="txtSum" runat="server" Width="21px"></asp:TextBox>
 </div>
            <asp:Label ID="Label2" runat="server" Width="350px"  Visible="False"></asp:Label><br />
The above is all it takes for the markup. Here's the codebehind:

using System;
using System.Drawing;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace SumCaptcha
{
    public partial class SumCaptchaControl : System.Web.UI.UserControl
    {
        public bool Success = false;
        protected void Page_Load(object sender, EventArgs e)
        {
            // if the page is first requested  and not postback, we need to initialize our numbers:
            if (!IsPostBack)
            {
                System.Random rand = new Random((int)DateTime.Now.Ticks);
                int num1 = rand.Next(1, 10);
                int num2 = rand.Next(1, 10);
                int total = num1 + num2;
                Session["total"] = total;
                lblNum1.Text = num1.ToString();
                lblNum2.Text = num2.ToString();
            }
            else
            {
              Success=  Validate();
            }
        }

        public bool Validate()
        {
            // 1. First, make sure user entered a number in the sum textbox:
            // all these labels are optional, you can just handle the public Success field being True|False
            int sum = 0;
            if (!int.TryParse(txtSum.Text, out sum))
            {
                Label2.Visible = true;
                Label2.Text = "Need to put a sum in the textbox, Captain.";
                Label2.BackColor = Color.Red;
                return false;
            }

            // 2. Compare their entry with the stored sum of the two numbers:
            if (sum != (int)Session["total"])
            {
                // They got it wrong...
                Label2.Visible = true;
                Label2.BackColor = Color.Red;
                Label2.Text = "Failed Bot check. Please try again.";
                return false;
            }
            else
            {
                // They got it right:
                Label2.Visible = true;
                Label2.BackColor = Color.LightGreen;
                Label2.Text = "Success!";
                return true;
            }
        }
    }
}
And here is how you would use it inside your own ASP.NET Form:

<%@ Page language="C#" %>
<%@ Import Namespace="SumCaptcha"%>
<%@ Import Namespace="System.Drawing.Internal"%>
<%@ Import Namespace="System.Drawing"%>
<%@ Register src="SumCaptchaControl.ascx" tagname="SumCaptchaControl" tagprefix="uc1" %>
<script runat="server" language="C#">
    
    protected void Button1_Click(object sender, EventArgs e)
    {
        if (SumCaptchaControl1.Success)
        {
            // your business logic goes here:
            Response.Redirect("http://www.eggheadcafe.com");
        }
        
    }
</script>
<HTML>
<head>

</head>
<body>
<BaseFont face="Verdana" />
<Form runat="server" id="Form1">
<!-- This is where all your regular formfields would go. We just have one sample "email" field here. -->
<asp:Label runat=server Text="Enter your email:"/>
<asp:TextBox runat=Server id=email />
<br />
<uc1:SumCaptchaControl ID="SumCaptchaControl1" runat="server" />   
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Submit" Width="120px" />
</Form>
</body>
</HTML>












Sample behavior:
 



You can download the sample Visual Studio 2008 solution here.

Biography - Peter Bromberg
Peter Bromberg is a C# MVP, MCP, and .NET expert who has worked in banking, financial and telephony for over 20 years. Pete focuses exclusively on the .NET Platform, and currently develops SOA and other .NET applications for a Fortune 500 clientele. Peter enjoys producing digital photo collage with Maya,playing jazz flute, the beach, and fine wines. You can view Peter's UnBlog and IttyUrl sites.
Please post questions at forums, not via email!

button
Article Discussion: An Ultra-Simple Sum of Numbers Captcha UserControl
Peter Bromberg posted at Thursday, May 21, 2009 10:05 AM
Original Article