Tuesday 10 September 2013

What is CAPTCHA? How to use CAPTCHA code in ASP.NET web application?


In this article I will explain what is CAPTCHA? How to use CAPTCHA code in ASP.NET web application?
A CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) is a challenge-response system test designed to differentiate humans from automated programs. A CAPTCHA differentiates between human and bot by setting some task that is easy for most humans to perform but is more difficult and time-consuming for current bots to complete.
HOW TO USE CAPTCHA:

Copy the below code and paste it in a separate class in Business Logic Layer

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Drawing.Design;

/// CAPTCHA Image generation, on each Image property call,
/// based on all other customizable property values.
///

[DefaultProperty("Text")]
public class CaptchaImage
{
    private Random _random = new Random();

    public CaptchaImage() { Text = ""; }

    #region Bitmap

    [Browsable(false)]
    [Category("Bitmap")]
    [Description("Generated image")]
    public Bitmap Image
    {
        get
        {
            Bitmap bitmap = new Bitmap(_width, _height,
                PixelFormat.Format32bppPArgb);

            Graphics g = null;
            Font font = null;
            HatchBrush textBrush = null;
            HatchBrush backBrush = null;
            try
            {
                // Fill Background
                g = Graphics.FromImage(bitmap);
                g.SmoothingMode = SmoothingMode.AntiAlias;
                Rectangle rect = new Rectangle(0, 0, _width, _height);
                textBrush = new HatchBrush(_textStyle,
                    _textForeColor, _textBackColor);
                backBrush = new HatchBrush(_backStyle,
                    _backForeColor, _backBackColor);
                g.FillRectangle(backBrush, rect);

                // Write Text
                StringFormat stringFormat = new StringFormat();
                stringFormat.Alignment = StringAlignment.Center;
                stringFormat.LineAlignment = StringAlignment.Center;
                font = new Font(_fontName, _fontSize, _fontStyle);
                GraphicsPath path = new GraphicsPath();
                path.AddString(_text, font.FontFamily,
                    (int)font.Style, font.Size, rect, stringFormat);

                // Warp Text
                if (_warp > 0)
                {
                    Matrix matrix = new Matrix();
                    float warp = 10 - _warp * 6 / 100;
                    PointF[] points = {
                                                    new PointF(_random.Next(rect.Width) / warp,
                                _random.Next(rect.Height) / warp),
                                                    new PointF(rect.Width - _random.Next(rect.Width) / warp,
                                _random.Next(rect.Height) / warp),
                                                    new PointF(_random.Next(rect.Width) / warp,
                                rect.Height - _random.Next(rect.Height) / warp),
                                                    new PointF(rect.Width - _random.Next(rect.Width) / warp,
                                rect.Height - _random.Next(rect.Height) / warp) };
                    path.Warp(points, rect, matrix, WarpMode.Perspective, 0F);
                }
                g.FillPath(textBrush, path);

                // Random Noise over Text
                if (_noise > 0)
                {
                    int maxDim = Math.Max(rect.Width, rect.Height);
                    int radius = (int)(maxDim * _noise / 3000);
                    int maxGran = (int)(rect.Width * rect.Height
                        / (100 - (_noise >= 90 ? 90 : _noise)));
                    for (int i = 0; i < maxGran; i++)
                        g.FillEllipse(textBrush,
                            _random.Next(rect.Width), _random.Next(rect.Height),
                            _random.Next(radius), _random.Next(radius));
                }

                // Draw Lines over Text
                if (_lines > 0)
                {
                    int lines = ((int)_lines / 30) + 1;
                    using (Pen pen = new Pen(textBrush, 1))
                        for (int i = 0; i < lines; i++)
                        {
                            PointF[] points = new PointF[lines > 2 ? lines - 1 : 2];
                            for (int j = 0; j < points.Length; j++)
                                points[j] = new PointF(_random.Next(rect.Width),
                                    _random.Next(rect.Height));
                            g.DrawCurve(pen, points, 1.75F);
                        }
                }
            }
            finally
            {
                // Dispose GDI+ objects
                if (g != null)
                    g.Dispose();
                if (font != null)
                    font.Dispose();
                if (textBrush != null)
                    textBrush.Dispose();
                if (backBrush != null)
                    backBrush.Dispose();
            }

            return bitmap;
        }
    }

    private int _width = 100;
    [Category("Bitmap")]
    [Description("Image Width")]
    public int Width
    {
        get { return _width; }
        set
        {
            if (value < 10 || value > 1000)
                throw new Exception("Image Width must be between 10 and 1000");
            _width = value;
        }
    }

    private int _height = 60;
    [Category("Bitmap")]
    [Description("Image Height")]
    public int Height
    {
        get { return _height; }
        set
        {
            if (value < 10 || value > 1000)
                throw new Exception("Image Height must be between 10 and 1000");
            _height = value;
        }
    }
    #endregion

    #region Effects

    private int _noise = 100;
    [Category("Effects")]
    [Description("Noise Factor")]
    public int NoiseFactor
    {
        get { return _noise; }
        set
        {
            if (value < 0 || value > 100)
                throw new Exception("Noise Factor must be between 0 and 100");
            _noise = value;
        }
    }

    private int _warp = 100;
    [Category("Effects")]
    [Description("Warp Factor")]
    public int WarpFactor
    {
        get { return _warp; }
        set
        {
            if (value < 0 || value > 100)
                throw new Exception("Warp Factor must be between 0 and 100");
            _warp = value;
        }
    }

    private int _lines = 100;
    [Category("Effects")]
    [Description("Lines Factor")]
    public int LinesFactor
    {
        get { return _lines; }
        set
        {
            if (value < 0 || value > 100)
                throw new Exception("Lines Factor must be between 0 and 100");
            _lines = value;
        }
    }
    #endregion

    #region Brushes

    public HatchStyle _textStyle = HatchStyle.NarrowHorizontal;
    [Category("Hatch Brush Text")]
    [Description("Hatch Brush Text Style")]
    public HatchStyle TextStyle
    {
        get { return _textStyle; }
        set { _textStyle = value; }
    }

    private Color _textForeColor = Color.Black;
    [Category("Hatch Brush Text")]
    [Description("Hatch Brush Text Fore Color")]
    public Color TextForeColor
    {
        get { return _textForeColor; }
        set { _textForeColor = value; }
    }

    private Color _textBackColor = Color.DarkGray;
    [Category("Hatch Brush Text")]
    [Description("Hatch Brush Text Background Color")]
    public Color TextBackColor
    {
        get { return _textBackColor; }
        set { _textBackColor = value; }
    }

    public HatchStyle _backStyle = HatchStyle.DottedGrid;
    [Category("Hatch Brush Background")]
    [Description("Hatch Brush Background Style")]
    public HatchStyle BackgroundStyle
    {
        get { return _backStyle; }
        set { _backStyle = value; }
    }

    private Color _backForeColor = Color.LightGray;
    [Category("Hatch Brush Background")]
    [Description("Hatch Brush Background Fore Color")]
    public Color BackgroundForeColor
    {
        get { return _backForeColor; }
        set { _backForeColor = value; }
    }

    private Color _backBackColor = Color.White;
    [Category("Hatch Brush Background")]
    [Description("Hatch Brush Background Background Color")]
    public Color BackgroundBackColor
    {
        get { return _backBackColor; }
        set { _backBackColor = value; }
    }
    #endregion

    #region Text

    private string _text = "";
    [Category("Text"),
    Description("Text string. Empty to auto-generate random string.")]
    public string Text
    {
        get { return _text; }
        set
        {
            if (value == null
                || (value.Length != 0 && value.Length < 2)
                || value.Length > 10)
                throw new Exception("Text Length must be between 2 and 10");

            _text = value;
            if (_text.Length == 0)
                for (int i = 0; i < _length; i++)
                {
                    char c;
                    do
                        c = _charSet[_random.Next(0, _charSet.Length)];
                  while (_unique && _length <= _charSet.Length && _text.IndexOf(c) >= 0);
                    _text += c;
                }
            _length = _text.Length;
        }
    }

    private string _charSet = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
    [Category("Text")]
    [Description("Character set for auto-text generation")]
    public string CharacterSet
    {
        get { return _charSet; }
        set
        {
            if (value == null || value.Length < 2)
                throw new Exception("Minimum character set size is 2");
            _charSet = value;
            Text = "";
        }
    }

    private int _length = 5;
    [Category("Text")]
    [Description("Text Length")]
    public int Length
    {
        get { return _length; }
        set
        {
            if (value < 2 || value > 10)
                throw new Exception("Text Length must be between 2 and 10");
            _length = value;
            Text = "";
        }
    }

    private bool _unique = true;
    [Category("Text")]
    [Description("Unique characters or not")]
    public bool Unique
    {
        get { return _unique; }
        set
        {
            _unique = value;
            Text = "";
        }
    }
    #endregion

    #region Font

    private string _fontName = "Tahoma";
    [Category("Font")]
    [Description("Font Name")]
    [TypeConverter(typeof(FontConverter.FontNameConverter))]
    [Editor("System.Drawing.Design.FontNameEditor", typeof(UITypeEditor))]
    public string FontName
    {
        get { return _fontName; }
        set { _fontName = value; }
    }

    private int _fontSize = 25;
    [Category("Font")]
    [Description("Font Size")]
    public int FontSize
    {
        get { return _fontSize; }
        set { _fontSize = value; }
    }

    private FontStyle _fontStyle = FontStyle.Bold;
    [Category("Font")]
    [Description("Font Style")]
    public FontStyle FontStyle
    {
        get { return _fontStyle; }
        set { _fontStyle = value; }
    }
    #endregion
}



First we need to create the defult.aspx page as shown below

 
     <table id="tblCaptcha" runat="server">
         <tr>
             <td >

<img id="imgCP" runat="server" border="0" height="70" src="default.aspx?captcha=true"/>
              </td>
              <td>
 <asp:TextBox ID="CaptchaCode" runat="server"></asp:TextBox>                                                                            <asp:ImageButton ID="imgbtnRefresh" runat="server" Height="20px" ImageUrl="~/Images/refresh_but.png" OnClick="imgbtnRefresh_Click" />
  <asp:Label ID="Label2" runat="server" Text="Label" ></asp:Label><br />
<span>(Enter the letters displayed in the image above. If you cannot read the letters, press the Refresh button.)</span>
            </td>
        </tr>
     </table>

If you use the above code the design will be like this




Next we need to write Code i.e, aspx.cs file as follows:

       protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.QueryString["captcha"] == "true")
                GetCaptchaImage();//th
            else
            {
                if (IsPostBack)
                    _result = (IsValidCaptcha() ? "Valid Code" : "Invalid Code");
                CreateCaptchaImage();
            }
        }

        // To Show the Generated CaptchaImage

        private void GetCaptchaImage()
        {
            CaptchaImage image = Session[CAPTCHA_ID] as CaptchaImage;
            Debug.Assert(image != null);
            Response.Clear();
            Response.ContentType = "image/jpeg";
            image.Image.Save(Response.OutputStream, ImageFormat.Jpeg);
        }

        // Generate a new CaptchaImage instance, with custom values
        private void CreateCaptchaImage()
        {
            CaptchaImage image = new CaptchaImage();
            Session[CAPTCHA_ID] = image;

            // customize CaptchaImage instance here
//if u give only numerical then you will get the captcha with numbers only. If           you include the alphabets along with numerical then will get the captcha image with numbers & alphabet.
            image.CharacterSet = "2345678910";
        }

        // Returns true if valid entered code (case insensitive comparison!)
        private bool IsValidCaptcha()
        {
            CaptchaImage image = Session[CAPTCHA_ID] as CaptchaImage;
            return (String.Compare(image.Text, CaptchaCode.Text, true) == 0);
        }
        protected void imgbtnRefresh_Click(object sender, ImageClickEventArgs e)
        {
            CaptchaCode.Text = string.Empty;
        }



No comments:

Post a Comment