Nov 19, 2008

Captcha Image using C# in Asp.Net


Captcha Image using C# in Asp.Net


What is Captcha Image?

In web when ever you are registering on any site normally they are asking at the end of page for enter Image code/Challenge Image/Image verification code etc. This type of image called Captcha Image.


What is the use of Captcha?


Captcha is a type of challenge-response test used in computing to ensure that the response is not generated by a computer. The process usually involves one computer (a server) asking a user to complete a simple test which the computer is able to generate and grade. Because other computers are unable to solve the CAPTCHA, any user entering a correct solution is presumed to be human.

A best technique to restrict automatic form submissions when developing a web page is to add some kind of verification. And as per my knowledge image verification is the best way, it’s also called Captcha image. In this process dynamically we are creating a image with random string either string, number or alphanumeric and display on the web page. After that at the time of form submission user is asked to enter same code in the text box as shown in that image. Once form is submitted then we can compare both auto generated value and entered by user. Because there id no other good way to protect your webworms from spammers (auto submission).


How can we do that?

Here is the details explanation with Code snippets.

This is the default.aspx (partially)
Html Code

    <asp:Label ID="lblmsg" runat="server" Font-Bold="True" ForeColor="Red" Text="">asp:Label>
    <br />
    Enter code shown below in text box.
    <asp:TextBox ID="txtimgcode" runat="server" ValidationGroup="1">asp:TextBox><br />
        <img height="70" width="200" src="CImage.aspx" width="176" alt="" />
        <br />
    div>
    <asp:Button ID="Button1" runat="server" Text="Validate" onclick="Button1_Click" />

In above code there are three control Lable control to display message weather entered code is matched or not. TextBox to take input from user and Image box to hold a image autogenerated by CImage.aspx page. Before that we will see default.aspx.cs page code


protected void Button1_Click(object sender, EventArgs e)
    {
        if (this.txtimgcode.Text == this.Session["CaptchaImageText"].ToString())
        {
            lblmsg.Text = "Excellent.......";
        }
        else
        {
            lblmsg.Text = "image code is not valid.";
        }
        this.txtimgcode.Text = "";
    }

In button’s click event we are just checking entered value with stored value in session. And display appropriate message on the screen.

CImage.aspx page
Remove all the code except first line

Like 

Main code is here witch is calling a method to generate random no string and pass it to class file which will generate image with same string and retrun it as a Jpeg format.

Here is the details code.

using System.Drawing.Imaging;

public partial class CImage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Create a random code and store it in the Session object.
        this.Session["CaptchaImageText"] = GenerateRandomCode();

        // Create a CAPTCHA image using the text stored in the Session object.
        RandomImage ci = new RandomImage(this.Session["CaptchaImageText"].ToString(), 300, 75);

        // Change the response headers to output a JPEG image.
        this.Response.Clear();
        this.Response.ContentType = "image/jpeg";

        // Write the image to the response stream in JPEG format.
        ci.Image.Save(this.Response.OutputStream, ImageFormat.Jpeg);

        // Dispose of the CAPTCHA image object.
        ci.Dispose();
    }
  
    // Function to generate random string with Random class.

    private string GenerateRandomCode()
    {
        Random r = new Random();
        string s = "";
        for (int j = 0; j <>
        {
            int i = r.Next(3);
            int ch;
            switch (i)
            {
                case 1:
                    ch = r.Next(0, 9);
                    s = s + ch.ToString();
                    break;
                case 2:
                    ch = r.Next(65, 90);
                    s = s + Convert.ToChar(ch).ToString();
                    break;
                case 3:
                    ch = r.Next(97, 122);
                    s = s + Convert.ToChar(ch).ToString();
                    break;
                default:
                    ch = r.Next(97, 122);
                    s = s + Convert.ToChar(ch).ToString();
                    break;
            }
            r.NextDouble();
            r.Next(100, 1999);
        }
        return s;
    }
}


And finally at last the code for RandomImage class which is genrating Image with the help of BitMap class.

//Extra name space
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
public class RandomImage
{
//Default Constructor
      public RandomImage(){}
//property
      public string Text
        {
            get { return this.text; }
        }
    public Bitmap Image
    {
        get { return this.image; }
    }
    public int Width
    {
        get { return this.width; }
    }
    public int Height
    {
        get { return this.height; }
    }
//Private variable
    private string text;
    private int width;
    private int height;
    private Bitmap image;

    private Random random = new Random();
    //Methods decalration
    public RandomImage(string s, int width, int height)
    {
          this.text = s;
          this.SetDimensions(width, height);
          this.GenerateImage();
    }

    public void Dispose()
    {
        GC.SuppressFinalize(this);
        this.Dispose(true);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
            this.image.Dispose();
    }

    private void SetDimensions(int width, int height)
    {
          if (width <= 0)
                throw new ArgumentOutOfRangeException("width", width, "Argument out of range, must be greater than zero.");
          if (height <= 0)
                throw new ArgumentOutOfRangeException("height", height, "Argument out of range, must be greater than zero.");
          this.width = width;
          this.height = height;
    }

    private void GenerateImage()
    {
          Bitmap bitmap = new Bitmap(this.width, this.height, PixelFormat.Format32bppArgb);

          Graphics g = Graphics.FromImage(bitmap);
          g.SmoothingMode = SmoothingMode.AntiAlias;
          Rectangle rect = new Rectangle(0, 0, this.width, this.height);

          HatchBrush hatchBrush = new HatchBrush(HatchStyle.SmallConfetti, Color.LightGray, Color.White);
          g.FillRectangle(hatchBrush, rect);

          SizeF size;
          float fontSize = rect.Height + 1;
        Font font;
       
          do
          {
                fontSize--;
            font = new Font(FontFamily.GenericSansSerif, fontSize, FontStyle.Bold);
                size = g.MeasureString(this.text, font);
          } while (size.Width > rect.Width);

          StringFormat format = new StringFormat();
          format.Alignment = StringAlignment.Center;
          format.LineAlignment = StringAlignment.Center;

          GraphicsPath path = new GraphicsPath();
          //path.AddString(this.text, font.FontFamily, (int) font.Style, font.Size, rect, format);
        path.AddString(this.text, font.FontFamily, (int)font.Style, 75, rect, format);
          float v = 4F;
          PointF[] points =
          {
                new PointF(this.random.Next(rect.Width) / v, this.random.Next(rect.Height) / v),
                new PointF(rect.Width - this.random.Next(rect.Width) / v, this.random.Next(rect.Height) / v),
                new PointF(this.random.Next(rect.Width) / v, rect.Height - this.random.Next(rect.Height) / v),
                new PointF(rect.Width - this.random.Next(rect.Width) / v, rect.Height - this.random.Next(rect.Height) / v)
          };
          Matrix matrix = new Matrix();
          matrix.Translate(0F, 0F);
          path.Warp(points, rect, matrix, WarpMode.Perspective, 0F);

          hatchBrush = new HatchBrush(HatchStyle.Percent10, Color.Black, Color.SkyBlue);
          g.FillPath(hatchBrush, path);

          int m = Math.Max(rect.Width, rect.Height);
          for (int i = 0; i < (int) (rect.Width * rect.Height / 30F); i++)
          {
                int x = this.random.Next(rect.Width);
                int y = this.random.Next(rect.Height);
                int w = this.random.Next(m / 50);
                int h = this.random.Next(m / 50);
                g.FillEllipse(hatchBrush, x, y, w, h);
          }

          font.Dispose();
          hatchBrush.Dispose();
          g.Dispose();

          this.image = bitmap;
    }
}
 Happy protecting Auto submission...................




2 comments:

Anonymous

how to use captcha in asp.net using C#.
Sir plz send me code on my id-mohdar7d@gmail.com

Tarun Dudhatra

Hi,

Necessary code is already written in the above article you can copy it.

Thanks

Post a Comment

Author Profile

Total Pageviews

Categories

Followers

 

Sponsors