Application Plug-ins Code Example Update

How To Create a CAPTCHA Graphic in VB.NET

November 6th, 2007

An Example of a CAPTCHA Generated By This Class

In this article we’ll be creating a class to generate CAPTCHA graphics that you can use on web sites to help authenticate users as being human and not an automated process.

What Is CAPTCHA

CAPTCHA is an abbreviation for Completely Automated Public Turing test to tell Computers and Humans Apart. This method uses images of words or numbers that are, in theory, distorted and jumbled enough so that an optical character recognition program can’t read them but a human should be able to do so easily.

I’m not a big fan of this method myself since I think it interferes with the user experience. However, there is plenty of demand for them to be placed into systems that interact with the public on the Internet.

The CAPTCHA Class

You can download the CAPTCHA class source code here.

This class is a simple one that builds a 5 character numeric string and places it on a grid background with random ‘noise’. Our properties include the height, width, and font along with the randomly generated value between 10000 and 99999 and the matching bitmap. The new method is available as a parameterless version for subclassing and one that allows you to pass in the height, width, and font.

The core routine is the GenerateNewCaptcha shown here:

    Public Sub GenerateNewCaptcha()
        If _captchaFont Is Nothing OrElse _captchaHeight = 0 OrElse _captchaWidth = 0 Then
            Exit Sub
        End If
        _captchaCode = RandomValue.Next(10000, 100000).ToString
        _captchaImage = New Bitmap(_captchaWidth, _captchaHeight)
        Using CaptchaGraphics As Graphics = Graphics.FromImage(CaptchaImage)
            Using BackgroundBrush As New Drawing2D.HatchBrush(Drawing2D.HatchStyle.SmallGrid, Color.DimGray, Color.WhiteSmoke)
                CaptchaGraphics.FillRectangle(BackgroundBrush, 0, 0, _captchaWidth, _captchaHeight)
            End Using
            Dim CharacterSpacing As Integer = (_captchaWidth \ 5) - 1
            Dim HorizontalPosition As Integer
            Dim MaxVerticalPosition As Integer
            For Each CharValue As Char In _captchaCode.ToCharArray
                MaxVerticalPosition = _captchaHeight - Convert.ToInt32(CaptchaGraphics.MeasureString(CharValue, _captchaFont).Height)
                CaptchaGraphics.DrawString(CharValue, _captchaFont, Brushes.DimGray, HorizontalPosition, RandomValue.Next(0, MaxVerticalPosition))
                HorizontalPosition += CharacterSpacing + RandomValue.Next(-1, 1)
            Next
            For Counter As Integer = 0 To 24
                CaptchaGraphics.FillEllipse(Brushes.DimGray, RandomValue.Next(1, _captchaWidth), RandomValue.Next(1, _captchaHeight), RandomValue.Next(1, 4), RandomValue.Next(1, 4))
            Next
            For Counter As Integer = 0 To 24
                CaptchaGraphics.FillEllipse(Brushes.WhiteSmoke, RandomValue.Next(1, _captchaWidth), RandomValue.Next(1, _captchaHeight), RandomValue.Next(1, 4), RandomValue.Next(1, 4))
            Next
        End Using
    End Sub

Let’s look at some of the details of this routine.

First, notice that we’re generating random numbers in several places, most notably to generate the main code value. We also use random numbers to place the numbers and the noise bits.

The HatchBrush object is used to draw the grid background. This style could be changed to a different pattern. There are several variations you could try to get a unique effect. You could even randomize the background.

The characters from the randomly generated number are drawn onto the graphic one character at a time and are randomly placed along the vertical axis and slightly off kilter on the horizontal one.

The FillEllipse method of the Graphics object is used to create the noise at 50 different random points on the graphic. These little marks help obscure the actual characters from OCR’s and sometimes from humans as well.

Using the Class

Using the class is simple. You just create the class, display the graphic from it and verify user input against the value stored in the class. You can also regenerate the value if the user requests it. Remember that you will need to save the generated bitmap to disk in order to display it to a web user in an ASP.NET application.

More You Can Add

There are several things you could add to this class to enhance it. You could:

- Add the ability to accept strings
- Add the ability to dynamically size the strings and the resulting bitmap
- Add more distortion by using Graphics method to twist the output
- Add more background noise options

That’s all for this example. Let me know if you have any questions or observations by this example by leaving me a comment.

Share This Article: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati
  • DotNetKicks
  • DZone

Entry Filed under: Code Examples


Rate This Article:

Not That GoodCould Be BetterOKGoodGreat (8 votes, average: 4.75 out of 5)
Loading ... Loading ...

17 Comments Add your own

  • 1. Ashok  |  November 10th, 2007 at 7:34 pm

    Could provide a concrete example of using the captcha class? Thank you

  • 2. nilesh  |  November 13th, 2007 at 8:49 am

    please can you show the view of the bild simple software

  • 3. jfrankcarr  |  November 13th, 2007 at 8:58 am

    Thanks for stopping by Ashok and Nilesh,

    I’ll put together an example soon.

  • 4. Naafraat  |  November 18th, 2007 at 6:27 am

    I have seen some software tools that can read a Captcha graphic. How is that made possible. Can we do it using vb ?

  • 5. jfrankcarr  |  November 18th, 2007 at 12:48 pm

    Hi Naafraat,

    That would require Optical Character Reader (OCR) software. There are several tools available for .NET that can do this to varying degrees of success.

    How well it will decipher a CAPTCHA depends on the how hard the graphic is to read. In my example, the background grid graphic, random placement, font and dots would make it more difficult to OCR than plain text. If you applied more effects to the graphic it would make it more difficult to read, both for software and humans.

  • 6. Will N  |  January 17th, 2008 at 11:49 am

    How do you call this on your page to show the image?

  • 7. Keith B.  |  February 13th, 2008 at 3:21 pm

    Thanks for the code download and the tips. Nice post.

  • 8. David  |  February 26th, 2008 at 7:04 pm

    How do you call this class and use it in the page?

  • 9. Yoko  |  March 8th, 2008 at 10:39 pm

    Very informative. Thanks for sharing. :)

  • 10. Sanjai Malani  |  April 8th, 2008 at 1:37 am

    How do you call this class and use it in the page?

  • 11. Chuck  |  April 23rd, 2008 at 12:46 pm

    Sometime even more effective than captcha is just asking a simple, easy for humans to understand, hard for computers to grasp, question.

    Something as simple as “What is the sum of 10 and 5?”

    As far as I know, there are no bots out there yet smart enough to decipher such simple questions. A more sophisticated system could randomize a set of simple questions, to make it even more secure.

    What color is the sun? Yellow.
    What is the name of the planet on which we live? Earth

    and so on.

    Another advantage is this is more accessible to the vision-impaired.

  • 12. jfrankcarr  |  April 23rd, 2008 at 1:50 pm

    Hi Chuck,

    That is true. However, there are some blackhat scripts around that I’ve seen that will do some equation solving for captchas, particularly if it’s worded like you have in your comment.

    It’s a never ending battle against spam. While I don’t update this site often due to other commitments, I do keep an eye on it. In the past 3 months there have been over 10000 spam comment attempts. Akismet, while not perfect, does a good job of keeping them at bay.

  • 13. Cathy  |  July 21st, 2008 at 1:07 am

    Hi,

    I would like to know the design part of the code.. i.e.captcha

  • 14. Toner  |  December 23rd, 2008 at 5:30 pm

    To integrate:

    Dim myCaptcha As New Captcha
    myCaptcha.CaptchaHeight = 50
    myCaptcha.CaptchaWidth = 150
    myCaptcha.CaptchaFont = New Font(”Verdana”, 20, FontStyle.Regular)
    myCaptcha.GenerateNewCaptcha()

    myCaptcha.CaptchaImage.Save(Request.PhysicalApplicationPath & “images\captcha\” & myCaptcha.CaptchaCode & “.jpg”)
    ltrCaptcha.Text = myCaptcha.CaptchaCode

    imgCaptcha.ImageUrl = “../images/captcha/” & myCaptcha.CaptchaCode & “.jpg”

    Then on user input just check wheter invisble ltrCaptcha text is same as user’s input!

  • 15. venkat  |  March 31st, 2009 at 1:21 am

    hai..

    As you said you have to store the image in your project folder..

    If it happen like this.. if the number of user visiting that page in the

    sense - so there are no.of images stored in the My Images folder

    how to avoid this….

    how to use Character Instead of numbers… to display in the image..

  • 16. Webdevelopment company  |  September 19th, 2009 at 1:42 am

    As i am fresher in vb.net development thanks a lot to give me insight in captcha it helps me a lot.

  • 17. Vasanth  |  January 29th, 2010 at 11:25 am

    hi venkat ,

    we can also use characters or numbers or mixed characters otrnumbers by modifying the code with the single function which is shown below

    Imports System.Web.SessionState
    Imports System.Drawing
    Imports System.Drawing.Imaging

    Public Class Captcha

    Protected RandomValue As New Random

    Protected _captchaImage As Bitmap
    Protected _captchaHeight As Integer
    Protected _captchaWidth As Integer
    Protected _captchaFont As Font
    Protected _captchaCode As String

    ”’
    ”’ Useful for subclassing
    ”’
    ”’
    Public Sub New()

    End Sub

    ”’
    ”’ Loads properties and generates an initial captcha value and graphic
    ”’
    ”’ The Width of the Captcha Graphic
    ”’ The Height of the Captcha Graphic
    ”’ The Font of the Captcha Graphic
    ”’
    Public Sub New(ByVal imageWidth As Integer, ByVal imageHeight As Integer, ByVal imageFont As Font)
    _captchaHeight = imageHeight
    _captchaWidth = imageWidth
    _captchaFont = imageFont
    GenerateNewCaptcha()
    End Sub

    ”’
    ”’ Generates a new captcha value and graphic for the class
    ”’
    ”’
    Public Sub GenerateNewCaptcha()
    If _captchaFont Is Nothing OrElse _captchaHeight = 0 OrElse _captchaWidth = 0 Then
    Exit Sub
    End If
    _captchaCode = getrandomstring()
    _captchaImage = New Bitmap(_captchaWidth, _captchaHeight)
    Using CaptchaGraphics As Graphics = Graphics.FromImage(CaptchaImage)
    Using BackgroundBrush As New Drawing2D.HatchBrush(Drawing2D.HatchStyle.SmallGrid, Color.GhostWhite, Color.WhiteSmoke)
    CaptchaGraphics.FillRectangle(BackgroundBrush, 0, 0, _captchaWidth, _captchaHeight)
    End Using
    Dim CharacterSpacing As Integer = (_captchaWidth \ 5) - 1
    Dim HorizontalPosition As Integer
    Dim MaxVerticalPosition As Integer
    For Each CharValue As Char In _captchaCode.ToCharArray
    MaxVerticalPosition = _captchaHeight - Convert.ToInt32(CaptchaGraphics.MeasureString(CharValue, _captchaFont).Height)
    CaptchaGraphics.DrawString(CharValue, _captchaFont, Brushes.DimGray, HorizontalPosition, RandomValue.Next(0, MaxVerticalPosition))
    HorizontalPosition += CharacterSpacing + RandomValue.Next(-1, 1)
    Next
    For Counter As Integer = 0 To 24
    CaptchaGraphics.FillEllipse(Brushes.DimGray, RandomValue.Next(1, _captchaWidth), RandomValue.Next(1, _captchaHeight), RandomValue.Next(1, 4), RandomValue.Next(1, 4))
    Next
    For Counter As Integer = 0 To 24
    CaptchaGraphics.FillEllipse(Brushes.WhiteSmoke, RandomValue.Next(1, _captchaWidth), RandomValue.Next(1, _captchaHeight), RandomValue.Next(1, 4), RandomValue.Next(1, 4))
    Next
    End Using
    End Sub

    ”’
    ”’ The captcha bitmap image
    ”’
    ”’
    ”’
    ”’
    Private Function getrandomstring() As String
    Dim arrstr() As String
    arrstr = “A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,1,2,3,4,5,6,7,8,9,0″.Split(”,”.ToCharArray())
    Dim strdraw As String
    Dim r As Random
    r = New Random()
    strdraw = String.Empty
    Dim i As Integer
    For i = 0 To 4
    strdraw += arrstr(r.Next(0, arrstr.Length - 1))
    Next
    Return strdraw
    End Function
    Public Property CaptchaImage() As Bitmap
    Get
    Return _captchaImage
    End Get
    Set(ByVal value As Bitmap)
    _captchaImage = value
    End Set
    End Property

    ”’
    ”’ The value of the captcha
    ”’
    ”’
    ”’
    ”’
    Public Property CaptchaCode() As String
    Get
    Return _captchaCode
    End Get
    Set(ByVal value As String)
    _captchaCode = value
    End Set
    End Property

    ”’
    ”’ The Height of the Captcha Graphic
    ”’
    ”’
    ”’
    ”’
    Public Property CaptchaHeight() As Integer
    Get
    Return _captchaHeight
    End Get
    Set(ByVal value As Integer)
    _captchaHeight = value
    End Set
    End Property

    ”’
    ”’ The Width of the Captcha Graphic
    ”’
    ”’
    ”’
    ”’
    Public Property CaptchaWidth() As Integer
    Get
    Return _captchaWidth
    End Get
    Set(ByVal value As Integer)
    _captchaWidth = value
    End Set
    End Property

    ”’
    ”’ The Font of the Captcha Graphic
    ”’
    ”’
    ”’
    ”’
    Public Property CaptchaFont() As Font
    Get
    Return _captchaFont
    End Get
    Set(ByVal value As Font)
    _captchaFont = value
    End Set
    End Property

    End Class

Leave a Comment

Required

Required, hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed


Visit Me At My New Site, Programming In C#

Most Popular Articles

Highest Rated Articles

Categories

Most Recent Articles

Feeds

 Subscribe in a reader

To subscribe by e-mail
Enter your address here

Delivered by FeedBurner

VB Opportunities

Archives