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

Tagged as

Simple CAPTCHA, Create your own in C#

, 3 Aug 2010
Rate this:
Please Sign up or sign in to vote.
Create your own simple captcha in C#

Have you ever wondered how to create a Captcha for your web forms? Well, it's really simple and it won't take more than 100+ lines of code. This sample captcha that I will demonstrate will have random Font Type, Font Style, Font Color, Font Rotation, Background Style and Background Colour. Here are some samples of what this can generate:

Now without too much explanation, here it goes.

Step 1: In your web project, add a Generic Handler that's the file with the .ahsx extension. Ill just use this for this demo for simplicity and also it will compile on demand like a normal aspx file. It's up to you if you want to create a DLL which is better so you can reuse it in any projects you want. To do that, right click on the project on your Solution Explorer.

Then choose your file type, in this sample it's a Generic Handler.

Step 2: Once added you can start coding, here are the sample codes which you can freely copy.

<%@ WebHandler Language="C#" %>
using System;
using System.Web;
using System.Drawing;
using System.IO;
using System.Web.SessionState;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Drawing.Drawing2D;
public class Captcha : IHttpHandler, IReadOnlySessionState
{
public void ProcessRequest(HttpContext context)
{
int iHeight = 80;
int iWidth = 190;
Random oRandom = new Random();

int[] aBackgroundNoiseColor = new int[] { 150, 150, 150 };
int[] aTextColor = new int[] { 0, 0, 0 };
int[] aFontEmSizes = new int[] { 15, 20, 25, 30, 35 };

string[] aFontNames = new string[]
{
 "Comic Sans MS",
 "Arial",
 "Times New Roman",
 "Georgia",
 "Verdana",
 "Geneva"
};
FontStyle[] aFontStyles = new FontStyle[]
{  
 FontStyle.Bold,
 FontStyle.Italic,
 FontStyle.Regular,
 FontStyle.Strikeout,
 FontStyle.Underline
};
HatchStyle[] aHatchStyles = new HatchStyle[]
{
 HatchStyle.BackwardDiagonal, HatchStyle.Cross, 
	HatchStyle.DashedDownwardDiagonal, HatchStyle.DashedHorizontal,
 HatchStyle.DashedUpwardDiagonal, HatchStyle.DashedVertical, 
	HatchStyle.DiagonalBrick, HatchStyle.DiagonalCross,
 HatchStyle.Divot, HatchStyle.DottedDiamond, HatchStyle.DottedGrid, 
	HatchStyle.ForwardDiagonal, HatchStyle.Horizontal,
 HatchStyle.HorizontalBrick, HatchStyle.LargeCheckerBoard, 
	HatchStyle.LargeConfetti, HatchStyle.LargeGrid,
 HatchStyle.LightDownwardDiagonal, HatchStyle.LightHorizontal, 
	HatchStyle.LightUpwardDiagonal, HatchStyle.LightVertical,
 HatchStyle.Max, HatchStyle.Min, HatchStyle.NarrowHorizontal, 
	HatchStyle.NarrowVertical, HatchStyle.OutlinedDiamond,
 HatchStyle.Plaid, HatchStyle.Shingle, HatchStyle.SmallCheckerBoard, 
	HatchStyle.SmallConfetti, HatchStyle.SmallGrid,
 HatchStyle.SolidDiamond, HatchStyle.Sphere, HatchStyle.Trellis, 
	HatchStyle.Vertical, HatchStyle.Wave, HatchStyle.Weave,
 HatchStyle.WideDownwardDiagonal, HatchStyle.WideUpwardDiagonal, HatchStyle.ZigZag
};

//Get Captcha in Session
string sCaptchaText = context.Session["Captcha"].ToString();

//Creates an output Bitmap
Bitmap oOutputBitmap = new Bitmap(iWidth, iHeight, PixelFormat.Format24bppRgb);
Graphics oGraphics = Graphics.FromImage(oOutputBitmap);
oGraphics.TextRenderingHint = TextRenderingHint.AntiAlias;

//Create a Drawing area
RectangleF oRectangleF = new RectangleF(0, 0, iWidth, iHeight);
Brush oBrush = default(Brush);

//Draw background (Lighter colors RGB 100 to 255)
oBrush = new HatchBrush(aHatchStyles[oRandom.Next
	(aHatchStyles.Length-1)], Color.FromArgb((oRandom.Next(100, 255)), 
	(oRandom.Next(100, 255)), (oRandom.Next(100, 255))), Color.White);
oGraphics.FillRectangle(oBrush, oRectangleF);

System.Drawing.Drawing2D.Matrix oMatrix = new System.Drawing.Drawing2D.Matrix();
int i = 0;
for (i = 0; i <= sCaptchaText.Length - 1; i++)
{
 oMatrix.Reset();
 int iChars = sCaptchaText.Length;
 int x = iWidth / (iChars + 1) * i;
 int y = iHeight / 2;

 //Rotate text Random
 oMatrix.RotateAt(oRandom.Next(-40, 40), new PointF(x, y));
 oGraphics.Transform = oMatrix;

 //Draw the letters with Random Font Type, Size and Color
 oGraphics.DrawString
 (
 //Text
 sCaptchaText.Substring(i, 1),
 //Random Font Name and Style
 new Font(aFontNames[oRandom.Next(aFontNames.Length - 1)], 
	aFontEmSizes[oRandom.Next(aFontEmSizes.Length-1)], 
	aFontStyles[oRandom.Next(aFontStyles.Length - 1)]),  
 //Random Color (Darker colors RGB 0 to 100)
 new SolidBrush(Color.FromArgb(oRandom.Next(0, 100), 
	oRandom.Next(0, 100), oRandom.Next(0, 100))),
 x,
 oRandom.Next(10, 40)
 );
 oGraphics.ResetTransform();
}

MemoryStream oMemoryStream = new MemoryStream();
oOutputBitmap.Save(oMemoryStream, System.Drawing.Imaging.ImageFormat.Png);
byte[] oBytes = oMemoryStream.GetBuffer();

oOutputBitmap.Dispose();
oMemoryStream.Close();

context.Response.BinaryWrite(oBytes);
context.Response.End();
}
public bool IsReusable
{
get
{
 return false;
}
}
}

There is some commented explanation along the way so you won't get lost, but you can still ask me if you really need.

Step 3: Use that Captcha. On your aspx, add the following as an image like such:

<asp:Image ID="imgCaptcha" ImageUrl="Captcha.ashx" runat="server" />

If you noticed, it's like you are using it as an image, this is because it's an image rendered by that handler which you can see on the bottom part of the Captcha code.

context.Response.BinaryWrite(oBytes);

Step 4: Assign a text on that captcha on your code behind:

private void SetCaptchaText()
{
 Random oRandom = new Random();
 int iNumber = oRandom.Next(100000, 999999);
 Session["Captcha"] = iNumber.ToString();
}

Note: You may notice that I am using only numbers in this regard, this would be easy so users cannot be confused with l and 1, 0 and o, and other similar looking characters.
Note: By setting the session, you are also setting the text to render on the captcha and if you look at the captcha codes, it is in this section.

string sCaptchaText = context.Session["Captcha"].ToString();

Step 5: Compare that value to what the users had keyed into your text box:

if (Session["Captcha"].ToString() != txtCaptcha.Text.Trim())
 {
 Response.Redirect("Failed.aspx");
 }
 else
 {
 Response.Redirect("Success.aspx");
 }

That's it. Congratulations! You have created your own captcha.


License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Raymund Macaalay
Technical Lead
New Zealand New Zealand
http://nz.linkedin.com/in/macaalay
http://macaalay.com/
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
QuestionRefresh Button Pinmemberesmael taher13-Oct-13 0:01 
SuggestionGood but needs some improvements Pinmembermidix10-Jul-13 6:36 
GeneralMy vote of 5 PinmemberBhoomi Gajjar27-Jun-13 22:55 
QuestionImage not getting refreshed Pinmemberwonder-FOOL4-Jun-13 2:06 
QuestionWhere is the noise coming from? Pinmemberslbentley15-May-13 3:59 
AnswerRe: Where is the noise coming from? Pinmemberslbentley15-May-13 5:18 
GeneralRe: Where is the noise coming from? PinmemberAdamWhiteHat4-Jul-13 19:30 
SuggestionPlease set the content type before writing image; your browser will like you PinmemberArjan Pot4-Nov-12 20:36 
GeneralRe: Please set the content type before writing image; your browser will like you Pingroupjaspadee11-Jan-13 2:47 
GeneralMy vote of 5 Pinmemberjames337072-Oct-12 4:20 
GeneralMy vote of 5 PinmemberFarhan Ghumra17-Aug-12 0:08 
GeneralMy vote of 4 Pinmemberjohannesnestler25-Jul-12 3:12 
QuestionHave any tips? PinmemberEverson SB11-Jun-12 13:17 
GeneralImage not showing PinmemberChain_reaction10-Jan-11 9:41 
Hello, thanks for this nice tutorial, but I stumbled on some problems:
 
It's unclear to me where I need to put "SetCaptchaText();". I placed it into page_Load, because I assume that's where it's supposed to be.
Anyways, I've placed an image-tag on my page: <asp:Image ID="ImageCaptcha" ImageUrl="~/App_Code/Captcha.ashx" runat="server" />, with a link to the correct location of the code Handler.
Some more code Smile | :) :
 
protected void Page_Load(..)
{
if (!IsPostBack)
{
SetCaptchaText();
}
}
protected void Button3_Click(..)
{
try
{
int id = int.Parse(DropDownListLedenVerwijderen.SelectedItem.Value);
 
if (Session["Captcha"].ToString() != (TextBoxCaptcha.Text.Trim()))
{
Label3.Text += "fout";
TextBoxCaptcha.Text = "";
} ...
I've already tried a few other captchas, and I keep stumbling on the same problem with them: they refresh too fast.
 
Let's say I've code A, I enter code A into the textbox, and I click OK, after that my page reloads, and I've code B in my Session variable.
So when the code checks if the Captcha code is correct, it'll check code A vs code B. How do I solve this? I've already tried 15 different ways, and they all keep failing :/
I managed to get it working when I place the code INSIDE (!IsPostBack), but that makes it so that my captcha doesn't refresh when you get a wrong code.
 
Thanks a lot!
GeneralError Pinmemberlazybit2-Oct-10 1:13 
GeneralRe: Error PinmemberRaymund Macaalay2-Oct-10 13:39 
GeneralRe: Error Pinmemberlazybit2-Oct-10 17:19 
GeneralRe: Error PinmemberRaymund Macaalay3-Oct-10 21:06 
GeneralRe: Error Pingroupjaspadee11-Jan-13 2:49 
Generalimage not display Pinmemberniravsahayata23-Sep-10 4:32 
GeneralRe: image not display PinmemberRaymund Macaalay23-Sep-10 10:06 
GeneralMy vote of 5 PinmemberMember 432084415-Aug-10 10:50 
GeneralMy vote of 5 Pinmemberlyn.ma9-Aug-10 16:57 
GeneralMy Vote of 5 PinmemberManuel_Perez_II5-Aug-10 6:46 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140814.1 | Last Updated 4 Aug 2010
Article Copyright 2010 by Raymund Macaalay
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid