Click here to Skip to main content
Click here to Skip to main content

Generate an Image with a Random Number

By , 29 Nov 2006
 

Sample Generated Code Image

Introduction

We need to check if it is a real person who is registering on our Web site. So we decided to generate an image with a random code, hidden for robots, and feed it to the browser instead of a page response. We show it in our registration form, and let the user enter the code to check it.

Create the Web Project

  1. File -> New -> New project

    Create a new CodeImage Visual Basic ASP.NET Web Application.

Change the Web Form

  1. Rename WebForm1.aspx to CodeImage.aspx. Open it.

  2. Switch to HTML View (Right click -> View HTML source).

  3. Remove all HTML code. Leave only the <%@ Page ... %> header.

  4. Switch to Code View (Right click -> View Code).

Change the Page_Load method with the code to generate the random code image. Also set Session("hiddenCode") to allow code checks later:

Private Sub Page_Load(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.Load
    'Put user code to initialize the page here


    ' Create a Bitmap image

    Dim ImageSrc As System.Drawing.Bitmap = _
        New System.Drawing.Bitmap(155, 85)


    ' Fill it randomly with white pixels
    For iX As Integer = 0 To ImageSrc.Width - 1
        For iY As Integer = 0 To ImageSrc.Height - 1
            If Rnd() > 0.5 Then
                ImageSrc.SetPixel(iX, iY, System.Drawing.Color.White)
            End If
        Next iY
    Next iX

    ' Create an ImageGraphics Graphics object from bitmap Image
    Dim ImageGraphics As System.Drawing.Graphics = _
        System.Drawing.Graphics.FromImage(ImageSrc)

    ' Generate random code. 
    Dim hiddenCode As String = (Fix(Rnd() * 10000000)).ToString
    ' Set Session variable
    Session("hiddenCode") = hiddenCode

    ' Draw random code within Image
    Dim drawFont As New System.Drawing.Font("Arial", _
                    20, FontStyle.Italic)
    Dim drawBrush As New _
       System.Drawing.SolidBrush(System.Drawing.Color.Black)
    Dim x As Single = 5.0 + (Rnd() / 1) * (ImageSrc.Width - 120)
    Dim y As Single = 5.0 + (Rnd() / 1) * (ImageSrc.Height - 30)
    Dim drawFormat As New System.Drawing.StringFormat
    ImageGraphics.drawString(hiddenCode, drawFont, drawBrush, _
        x, y, drawFormat)

    ' Change reponse content MIME type
    Response.ContentType = "image/jpeg"

    ' Sent Image using Response OutputStream
    ImageSrc.Save(Response.OutputStream, _
                  System.Drawing.Imaging.ImageFormat.Jpeg)

    ' Dispose Objects used
    drawFont.Dispose()
    drawBrush.Dispose()
    ImageGraphics.Dispose()

End Sub

Build the Solution (F7), and run the application (F5).

Create the Check form.

  1. Create a New Default.aspx Web Form (Right click CodeImage project -> Add -> Add Web Form).

  2. Right click Default.aspx -> Set As Start Page. Open it.

  3. From the IDE menu, click View -> Toolbox. From the HTML tab, drag an Image control to the form. Right click Image -> Properties. Set the image source to "CodeImage.aspx". Set the alternate text to "Hidden Code". Click Apply. Click OK.

  4. From the HTML tab, drag a Label control to the form. Click it twice. Change the text to "Enter the code in the image:".

  5. From the Web Forms tab, drag a TextBox control to the form.

  6. From the Web Forms tab, drag a Button control to the form.

  7. From the Web Forms tab, drag a Label control to the form. Right click -> Properties. Set the Text property to Nothing.

Double click the Button1 button control, and change the Button1_Click code to:

Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click
    If TextBox1.Text <> Session("hiddenCode") Then
        Label1.Text = "Wrong Code!"
    Else
        Label1.Text = "Correct Code!"
    End If
End Sub

Build and run the Web application (F7) (F5).

Points of Interest

That's it!

History

Just posted.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

rmortega77
Software Developer CIMEX S.A.
Cuba Cuba
Member
Rodolfo Ortega is a Cuban Computer Scientist. He works as IT Auditor for the CIMEX S.A. subsidiary in Holguin, Cuba. He lives and works in Holguin, in the eastern part of the island of Cuba.

You can contact him at rodolfom[]cimex.com.cu for any personal message: Ideas on new articles, bibliography about new APIs, questions, are wellcome.

Submit questions related with current article to the article forum.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Generalin C# please...memberpradeep kumarappagari6 Dec '06 - 22:59 
this is really gr8 artical. iam trying to comvert in to c#, but iam facing problem with "Rnd()" for this what should i chang in the code. please can u.....
 
Pradeep Reddy

GeneralRe: in C# please...memberJasmine25017 Dec '06 - 6:39 
Chill for a few days... I'll post my C# control for this later. If you are just having trouble with the Rand function... post your question in the C# forum. It's pretty easy to use, but you might have a missing library or something.

 
"Quality Software since 1983!"
http://www.smoothjazzy.com/ - see the "Programming" section for (freeware) JazzySiteMaps, a simple application to generate .Net and Google-style sitemaps!

GeneralRe: in C# please...memberpradeep kumarappagari7 Dec '06 - 18:38 
thank u...Smile | :)
 
Pradeep Reddy

GeneralRe: in C# please...memberrmortega777 Dec '06 - 9:05 

First create the Random number generator and initialize it with time-dependent seed:
 
 Random Rnd = new Random();
 
By the way. We should do this in VisualBasic using Randomize().
 
Now change
 
 Rnd() > 0.5
 
With:
 
 r.NextDouble() > 0.5
 
And change
 
  (Fix(Rnd() * 10000000)).ToString
 
With
 
 r.Next().ToString();
 
And
 
 5.0 + (Rnd() / 1) * (ImageSrc.Width - 120)
 
With
 
 r.Next(5,120);
 

GeneralRe: in C# please...memberpradeep kumarappagari7 Dec '06 - 18:36 
thank you very much...i got itSmile | :)
 
Pradeep Reddy

GeneralHard to readmemberJasmine25016 Dec '06 - 10:45 
Great article but what struck me when I looked at the image at the top of the page is "that's kinda hard to read". I use a solid background (medium blue), on which I draw a few lines (light blue), then I make the letters in black, using a limited set of letters and symbols which are carefully chosen to be easy to recognize. Then I output the whole thing as a GIF. Mine is also done as a user control, so once it's all built, you can simply insert a server tag into the page, and it's all encapsulated nicely with it's own Validator that is capable of invalidating the whole form. I also use an encrypted value which is a HiddenField, so you don't have to use session values, and never have to worry about the plaintext of the verification code being output to the client, which a bot could theoretically read fairly simply. I will be posting an article about that eventually. You can see it in action on this page:
 
http://www.exit-planner.net/xpra/xpra_forward.aspx[^]
 
I use C#, so my article will be substantially different from this one, but you could implement the better drawing for your version.
 
"Quality Software since 1983!"
http://www.smoothjazzy.com/ - see the "Programming" section for (freeware) JazzySiteMaps, a simple application to generate .Net and Google-style sitemaps!

GeneralRe: Hard to readmemberM_Johnson6 Dec '06 - 21:36 
Not that I know too much about OCR.
But surly if the robot was to drop the all colours from the image except for black.Obtaining the code would be a trivial task.
 
I would see how rmortega77`s would not fall to the same simple attack.
 
And being hard to read should surly be the objective here, at least for an automated system.

GeneralRe: Hard to readmemberJasmine25017 Dec '06 - 6:37 
I thought of that, but the thing is... any of these image verifications are going to be subject to that problem. There's a certain point where it becomes so hard to read, that neither OCR nor a human being will be able to decode it. The image posted on the article is pretty close to that level. This system is not designed to defeat an OCR-based attack... and the spammers aren't going to go to that length. There's so many sites that don't use this that it's a waste of time for them to start doing that - they will just make their attack somewhere else. Remember, the power of spammers comes from the ability to hit millions of people in a short time... anything that slows them down is good. It doesn't have to be impossible to beat, it only has to be slightly harder than having nothing at all. It's like the lock on your front door... pretty low-tech security, and isn't going to stop someone who's determined to get in, but it's pretty effective at keeping most people out. When you start to go to extreme lengths, you start keeping your customers out too. If I can't read an image on the first or second try... I'm pretty frustrated. My eyesight is average 20/20, and I'm not color-blind or anything, but I see quite a few of these image verification things that I have trouble with.
 
I don't know of any research on this, but I would bet that OCR technology is getting pretty close to the human eye at recognising letters.
 
"Quality Software since 1983!"
http://www.smoothjazzy.com/ - see the "Programming" section for (freeware) JazzySiteMaps, a simple application to generate .Net and Google-style sitemaps!

AnswerRe: Hard to readmembermdekok30003 Nov '07 - 9:59 

Jasmine2501 wrote:
so hard to read

 
You can set it to display less random dots.
 
For iX As Integer = 0 To ImageSrc.Width - 1
For iY As Integer = 0 To ImageSrc.Height - 1
If Rnd() > 0.5 Then
ImageSrc.SetPixel(iX, iY, System.Drawing.Color.White)
End If
Next iY
Next iX

 
7 years of Web design
GeneralPerformance Fix...memberJon Rista29 Nov '06 - 10:46 
The part where you set pixels to white, which uses SetPixel, could be drastically improved. The problem with SetPixel is that each time it is called, it locks the bitmap in memory, gets the bitmap data, scans to the pixel that needs to be set, changes the pixel value, and unlocks the bitmap from memory.
 
You can greatly improve the performance of this code by using an unsafe function of a fixed code block to use pointers to set the pixels. When you do this, you lock the bitmap once, change all of the pixels with the one lock and a single incremental seek, and unlock at the end, rather than locking, seeking, changing, unlocking for each pixel.
 
Take a look at this article for more info:
 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp11152001.asp

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 29 Nov 2006
Article Copyright 2006 by rmortega77
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid