Wednesday, 26 March 2014

CAPTCHA Integration.

We are doing lots of daily routine work online now a days and therefore lots of vendors providing online membership in their site to maintain our daily or monthly tasks like to recharge your mobile, DTH recharge, Pay your bills etc. 

But some of the intruders tries to hangout their system by creating fraud members and so on using program or scripts. So to avoid these automated traffic/junk data for membership, registration, some specific checks/verifications are popular to be applied on site pages to verify human being submission/activity to conform valid membership/registration. 

One of the most famous approach is CAPTCHA. Which is actually an image containing some alpha/numeric/alphanumeric code which could not be easily understand by program and script. Thus CAPTCHA helps to avoid automated submission/registration etc. 

Today we are going to integrate a very basic level captcha which could be explored more to make it more complex to break for automated scripts or programs. 

1.       Create a class and name it as “GenerateRandomCaptchaImage.cs” and copy below code and paste in it.

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System;
public class GenerateRandomCaptchaImage
{

    #region [Constructor]
   
    public GenerateRandomCaptchaImage() { }
   
    #endregion

    #region [Properties]

    private string captchaText;
    public string CaptchaText
    {
        get { return this.captchaText; }
    }

    private Bitmap captchaImage;
    public Bitmap CaptchaImage
    {
        get { return this.captchaImage; }
    }

    private int captchaWidth;
    public int CaptchaWidth
    {
        get { return this.captchaWidth; }
    }

    private int captchaHeight;
    public int CaptchaHeight
    {
        get { return this.captchaHeight; }
    }

   
    #endregion

    #region [Private Variables]

    private Random random = new Random();

    #endregion

    #region [Methods]

    public GenerateRandomCaptchaImage(string s, int width, int height)
    {
        this.captchaText = s;
        this.SetDimensions(width, height);
        this.GenerateCaptchaImage();
    }
    public void Dispose()
    {
        GC.SuppressFinalize(this);
        this.Dispose(true);
    }
    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
            this.captchaImage.Dispose();
    }
    private void SetDimensions(int width, int height)
    {
        if (width <= 0)
            throw new ArgumentOutOfRangeException("width", width,
                "width must be greater than zero.");
        if (height <= 0)
            throw new ArgumentOutOfRangeException("height", height,
                "Height must be greater than zero.");
        this.captchaWidth = width;
        this.captchaHeight = height;
    }

    private void GenerateCaptchaImage()
    {
        //Declare bitmap variable.
        Bitmap captchaBitmap = new Bitmap
          (this.captchaWidth, this.captchaHeight, PixelFormat.Format32bppArgb);
        Graphics captchaGraphics = Graphics.FromImage(captchaBitmap);
        captchaGraphics.SmoothingMode = SmoothingMode.AntiAlias;
        Rectangle imageRect = new Rectangle(0, 0, this.captchaWidth, this.captchaHeight);
        HatchBrush hatchBrush = new HatchBrush(HatchStyle.SmallConfetti,
            Color.LightGray, Color.White);
        captchaGraphics.FillRectangle(hatchBrush, imageRect);
        SizeF size;
        float fontSize = imageRect.Height + 1;
        Font font;

        do
        {
            fontSize--;
            font = new Font(FontFamily.GenericSansSerif, fontSize, FontStyle.Bold);
            size = captchaGraphics.MeasureString(this.captchaText, font);
        } while (size.Width > imageRect.Width);
        StringFormat format = new StringFormat();
        format.Alignment = StringAlignment.Center;
        format.LineAlignment = StringAlignment.Center;
        GraphicsPath graphicPath = new GraphicsPath();
       
        graphicPath.AddString(this.captchaText, font.FontFamily, (int)font.Style, 75, imageRect, format);
        float v = 4F;
        PointF[] points =
          {
                new PointF(this.random.Next(imageRect.Width) / v, this.random.Next(
                   imageRect.Height) / v),
                new PointF(imageRect.Width - this.random.Next(imageRect.Width) / v,
                    this.random.Next(imageRect.Height) / v),
                new PointF(this.random.Next(imageRect.Width) / v,
                    imageRect.Height - this.random.Next(imageRect.Height) / v),
                new PointF(imageRect.Width - this.random.Next(imageRect.Width) / v,
                    imageRect.Height - this.random.Next(imageRect.Height) / v)
          };
        Matrix matrix = new Matrix();
        matrix.Translate(0F, 0F);
        graphicPath.Warp(points, imageRect, matrix, WarpMode.Perspective, 0F);
        hatchBrush = new HatchBrush(HatchStyle.Percent10, Color.Black, Color.SkyBlue);
        captchaGraphics.FillPath(hatchBrush, graphicPath);
        int m = Math.Max(imageRect.Width, imageRect.Height);
        for (int i = 0; i < (int)(imageRect.Width * imageRect.Height / 30F); i++)
        {
            int x = this.random.Next(imageRect.Width);
            int y = this.random.Next(imageRect.Height);
            int w = this.random.Next(m / 50);
            int h = this.random.Next(m / 50);
            captchaGraphics.FillEllipse(hatchBrush, x, y, w, h);
        }
        font.Dispose();
        hatchBrush.Dispose();
        captchaGraphics.Dispose();
        this.captchaImage = captchaBitmap;
    }

    #endregion
}



2.       Add a page and name it as “CaptchaImageGenerator.aspx” and copy below code and paste in “CaptchaImageGenerator.aspx.cs” file.
 using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing.Imaging;
public partial class CaptchaImageGenerator : System.Web.UI.Page
{
    #region [Events]
   
    protected void Page_Load(object sender, EventArgs e)
    {
        // Create a captcha code and keep it in session.
        this.Session["CaptchaImageText"] = GenerateRandomCaptchaCode();
        // generate Captcha image using the string code stored in the session.
        GenerateRandomCaptchaImage ci = new GenerateRandomCaptchaImage(this.Session
            ["CaptchaImageText"].ToString(), 300, 75);
        // Change the response headers/content type to output a jpg image.
        this.Response.Clear();
        this.Response.ContentType = "image/jpeg";
       
        // send image to the response stream in jpeg format.
        ci.CaptchaImage.Save(this.Response.OutputStream, ImageFormat.Jpeg);
        // Dispose the Captcha image object.
        ci.Dispose();
    }

    #endregion

    /// <summary>
    /// Generate random captcha code string.
    /// </summary>
    /// <returns></returns>

    #region [Methods]
   
    private string GenerateRandomCaptchaCode()
    {
        Random random = new Random();
        string s = "";
        for (int j = 0; j < 5;j++)
        {
            int i = random.Next(3);
            int ch;
            switch (i)
            {
                case 1:
                    ch = random.Next(0, 9);
                    s = s + ch.ToString();
                    break;
                case 2:
                    ch = random.Next(65, 90);
                    s = s + Convert.ToChar(ch).ToString();
                    break;
                case 3:
                    ch = random.Next(97, 122);
                    s = s + Convert.ToChar(ch).ToString();
                    break;
                default:
                    ch = random.Next(97, 122);
                    s = s + Convert.ToChar(ch).ToString();
                    break;
            }
            random.NextDouble();
            random.Next(100, 1999);
        }
        return s;
    }

    #endregion
}

Purpose of each file as created above is explained below.
1.       GenerateRandomCaptchaImage.cs :- This file contains code for captcha image generation. This code creates an image for provided randomly generated code with specified dimensions. “GenerateCaptchaImage” is the method which is responsible to generate desired image. You can modify code to give some variations to generated CAPTCHA image.

2.       CaptchaImageGenerator.aspx : - This file contains code for generation of random code to be appeared in CAPTCHA image. “GenerateRandomCaptchaCode” is the method used to generate random code. You can modify this code to give variation in code generation as per your choice. This page also returns generated CAPTCHA code in the form of image as response stream. So when we need to render CAPTCHA on page, we hust need to call this page to get CAPTCHA code.

Now create another page and name it as “Default.aspx” to render CAPTCHA code on page.
Default.aspx will be used to demo, how to display generated random code in the form of image in simple word how to display CAPTCHA on page and verify valid human submission.

Below is the code snippet which is used to render captcha code on page in image control. Add it in Default.aspx.
HTML Code -
<asp:ScriptManager ID="sm1" runat="server" />
    <div>
        <asp:Label ID="lblmsg" runat="server" Font-Bold="True" ForeColor="Red" Text=""></asp:Label>
        <br />
    </div>
    <asp:TextBox ID="txtimgcode" runat="server"></asp:TextBox>
    <br />
    <asp:UpdatePanel ID="upCaptchaCode" runat="server" UpdateMode="Always">
        <ContentTemplate>
        <asp:Panel ID="pnlCaptcha" runat="server" >
           
        </asp:Panel>
            <asp:Button ID="btnRegenerate" runat="server" Text="Reset" />
        </ContentTemplate>
    </asp:UpdatePanel>
    <br />
    <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button"/>

C# Code - Add below code in Default.aspx.cs file as created above.

protected void Page_Load(object sender, EventArgs e)
{
        //Clear already added image with captcha code.
        pnlCaptcha.Controls.Clear();

        //Create new image object to add in panel to display Captcha code.
        Image img1 = new Image();

//Create  new GUID string to unique request to generate different captcha code every time.
        string s = Guid.NewGuid().ToString();

//Set image url to content returned from CaptchaImageGenerator page on the  basis of unique request based on unique GUID query string.
        img1.ImageUrl = "~/CaptchaImageGenerator.aspx?p=" + s;

        //Now add created image object in panel on page controls to appear.
        pnlCaptcha.Controls.Add(img1);
}

protected void Button1_Click(object sender, EventArgs e)
{
//Compare entered captcha code with generated captcha code as stored in session when generated.
        if (this.txtimgcode.Text == this.Session["CaptchaImageText"].ToString())
        {
            lblmsg.Text = "Code matched.";
        }
        else
        {
            lblmsg.Text = "code does not match.";
        }
        this.txtimgcode.Text = "";
}

Now, using this simple code as per instructions as above you can create and integrate CAPTCHA code in your application with simplest CAPTCHA code. Now you can explore more and can play with the code to make it more complex to break.

So, enjoy CAPTCHA integration in your sites to verify human being submission to your application pages and avoid any traffic/junk data in your system which can be generated using automated scripts/programs.

See you in the next blog till then enjoy integration.

No comments:

Post a Comment