por Bruno de Andrade

Imagem de verificação (CAPTCHA) em C#

captcha

Certamente a grande maioria das pessoas já se deparou com um CAPTCHA tentando fazer um login em algum site por aí. Imagens CAPTCHA são imagens de verificação de segurança, na qual pode ser facilmente decifrada por um humano, mas que impedem que softwares automatizados invadam o sistema.
Como implementar isto em ASP.NET/C#? É só seguir os passos abaixos.

  • Crie uma nova página chamada Captcha.aspx. No Captcha.aspx.cs use o código abaixo. Ele irá gerar uma imagem com números randômicos e com algumas distorções e imperfeições, como na imagem acima.
private void Page_Load(object sender, System.EventArgs e)
{
    // Para gerar números randômicos.
    Random random = new Random();

    string s = "";
    for (int i = 0; i < 6; i++)
        s = String.Concat(s, random.Next(10).ToString());

    // Cria uma imagem bitmap de 32-bit.
    Bitmap bitmap = new Bitmap(173, 50, PixelFormat.Format32bppArgb);

    // Crie um objeto gráfico para o desenho.
    Graphics g = Graphics.FromImage(bitmap);
    g.SmoothingMode = SmoothingMode.AntiAlias;
    Rectangle rect = new Rectangle(0, 0, 173, 50);

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

    // Configura a fonte do texto.
    SizeF size;
    float fontSize = rect.Height + 1;
    Font font;

    // Ajuste o tamanho da fonte até que o texto 
    // se encaixe dentro da imagem.
    do
    {
        fontSize--;
        font = new Font(System.Drawing.FontFamily.GenericSerif.Name, 
                        fontSize, FontStyle.Bold);
        size = g.MeasureString(s, font);
    }
    while (size.Width > rect.Width);

    // Configure o formato de texto.
    StringFormat format = new StringFormat();
    format.Alignment = StringAlignment.Center;
    format.LineAlignment = StringAlignment.Center;

    // Cria uma deformação no formato dos números.
    GraphicsPath path = new GraphicsPath();
    path.AddString(s, font.FontFamily, (int)font.Style, font.Size, 
                   rect, format);
    float v = 4F;
    PointF[] points =
    {
         new PointF(
           random.Next(rect.Width) / v,
           random.Next(rect.Height) / v),
         new PointF(
           rect.Width - random.Next(rect.Width) / v,
           random.Next(rect.Height) / v),
         new PointF(
           random.Next(rect.Width) / v,
           rect.Height - random.Next(rect.Height) / v),
         new PointF(
           rect.Width - random.Next(rect.Width) / v,
           rect.Height - random.Next(rect.Height) / v)
     };
     Matrix matrix = new Matrix();
     matrix.Translate(0F, 0F);
     path.Warp(points, rect, matrix, WarpMode.Perspective, 0F);

     // Desenha o texto.
     hatchBrush = new HatchBrush(HatchStyle.LargeConfetti, 
                                 Color.LightGray, Color.DarkGray);
     g.FillPath(hatchBrush, path);

     // Coloca um pouco de partículas no fundo.
     int m = Math.Max(rect.Width, rect.Height);
     for (int i = 0; i < (int)(rect.Width * rect.Height / 30F); i++)
     {
         int x = random.Next(rect.Width);
         int y = random.Next(rect.Height);
         int w = random.Next(m / 50);
         int h = random.Next(m / 50);
         g.FillEllipse(hatchBrush, x, y, w, h);
     }
        
     //Cria uma session com o valor da imagem
     Session["CaptchaImageText"] = s;
       
     // Define a imagem.
     font.Dispose();
     hatchBrush.Dispose();
     g.Dispose();
     Response.ContentType = "image/GIF";
     bitmap.Save(Response.OutputStream, ImageFormat.Gif);
     bitmap.Dispose();
}
  • Na página onde deve ficar o CAPTCHA use estes componentes:
<body>
    <form id="form1" runat="server">
    <div>
	 <asp:Image ID="imgCaptcha" runat="server"/><br />
         <asp:TextBox ID="txtCaptcha" runat="server"/><br />
	 <asp:Button ID="btnSubmit" runat="server" onclick="Submit_Click" 
         Text="Submit"/><br />
	 <asp:Literal ID="litMessage" runat="server" />
    </div>
    </form>
</body>
  • E no código da mesma:
protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        imgCaptcha.ImageUrl = "Captcha.aspx";
    }    
}

protected void Submit_Click(object sender, EventArgs e) 
{
    if (CheckCaptcha())
        litMessage.Text = "Código correto";
    else
        litMessage.Text = "Código errado";
}

public bool CheckCaptcha()
{
    string strCaptcha = txtCaptcha.Text;
    if (Session["CaptchaImageText"].ToString() == strCaptcha)
       return true;
    else
       return false;
}

Na ação do botão a página irá verificar se os números digitados são iguais aos salvos na session.

Download dos arquivos:
Captcha.aspx
Captcha.aspx.cs
VerifyCaptcha.aspx
VerifyCaptcha.aspx.cs

Comentários

Carregando comentários

Postar um novo comentário



Processando...