تم الكتابة في محرم 30, 1429 02:50

 

السلام عليكم و رحمة الله وبركاته ...

كنت قد وعدتكم في هذا المقال بكتابة درس عن كيف تستخدم CAPTCHA في ASP.NET.

اليوم سوف أتطرق لهذا في هذه السطور القادمة.

ملاحظة: الموضوع الأصلي موجود في موقع Code Project في هذه الصفحة  و منقول بتصرف.

في البداية أنشئ صفحة و لنسميها Default.aspx و لنضع فيها:

  • Image اسمها Image1
  • TextBox اسمها TextBox1
  • Label اسمه Label1
  • Button اسمه Button1

و لنضع هذا الكود بداخل ملف Default.aspx.cs:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page
{
    // For generating random numbers.
    private Random random = new Random();

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            // Create a random code and store it in the Session object.
            Session["CaptchaImageText"] = GenerateRandomCode();
        }
        else
        {
            // On a postback, check the user input.
            if (TextBox1.Text == Session["CaptchaImageText"].ToString())
            {
                // Display an informational message.
                Label1.CssClass = "info";
                Label1.Text = "Correct!";
            }
            else
            {
                // Display an error message.
                Label1.CssClass = "error";
                Label1.Text = "ERROR: Incorrect, try again.";

                // Clear the input and create a new random code.
                TextBox1.Text = "";
                Session["CaptchaImageText"] = GenerateRandomCode();
            }
        }
    }

    //
    // Returns a string of six random digits.
    //
    private string GenerateRandomCode()
    {
        string s = "";
        for (int i = 0; i < 6; i++)
            s = String.Concat(s, this.random.Next(10).ToString());
        return s;
    }
}

 

في هذا الكود قمنا بانشاء رقم عشوائي و حفظة في Session اسمها CaptchImageText و تتغير كلما عملنا PageRefrsh

الآن للنشئ صفحة اسمها JpegImage.aspx و نضع الكود التالي في الملف JpegImage.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
        // Create a CAPTCHA image using the text stored in the Session object.
        CaptchaImage ci = new CaptchaImage(this.Session["CaptchaImageText"].ToString(), 200, 50, "Century Schoolbook");

        // 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();
}

هنا سوف نقوم بأنشاء الصورة و سيكون محتواها هو ما هو موجود في الـ Session التي أنشأناها في الصفحة Default.aspx ثم سوف نجعل هذه الصفحة تنتج ملف Jpeg بدلاً من HTML.

الآن في الصفحة Default.aspx نختار Image1 و نذهب للخصائص Properties و نضع القيمة ImageUrl تساوي الصفحة التي قمنا بإنشائها JpegImage.aspx.

 

الآن و المرحلة الأخيره هي انشاء كلاس Class اسمه CaptchaImage.cs ( و هي المسؤولة عن انشاء الصورة و تشويهها  عمل Noise للخلفيه) و نضع فيه الكود التالي:

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;

/// <summary>
/// Summary description for CaptchaImage
/// </summary>
public class CaptchaImage
{
    // Public properties (all read-only).
    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; }
    }

    // Internal properties.
    private string text;
    private int width;
    private int height;
    private string familyName;
    private Bitmap image;

    // For generating random numbers.
    private Random random = new Random();

    // ====================================================================
    // Initializes a new instance of the CaptchaImage class using the
    // specified text, width and height.
    // ====================================================================
    public CaptchaImage(string s, int width, int height)
    {
        this.text = s;
        this.SetDimensions(width, height);
        this.GenerateImage();
    }

    // ====================================================================
    // Initializes a new instance of the CaptchaImage class using the
    // specified text, width, height and font family.
    // ====================================================================
    public CaptchaImage(string s, int width, int height, string familyName)
    {
        this.text = s;
        this.SetDimensions(width, height);
        this.SetFamilyName(familyName);
        this.GenerateImage();
    }

    // ====================================================================
    // This member overrides Object.Finalize.
    // ====================================================================
    ~CaptchaImage()
    {
        Dispose(false);
    }

    // ====================================================================
    // Releases all resources used by this object.
    // ====================================================================
    public void Dispose()
    {
        GC.SuppressFinalize(this);
        this.Dispose(true);
    }

    // ====================================================================
    // Custom Dispose method to clean up unmanaged resources.
    // ====================================================================
    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
            // Dispose of the bitmap.
            this.image.Dispose();
    }

    // ====================================================================
    // Sets the image width and height.
    // ====================================================================
    private void SetDimensions(int width, int height)
    {
        // Check the width and 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;
    }

    // ====================================================================
    // Sets the font used for the image text.
    // ====================================================================
    private void SetFamilyName(string familyName)
    {
        // If the named font is not installed, default to a system font.
        try
        {
            Font font = new Font(this.familyName, 12F);
            this.familyName = familyName;
            font.Dispose();
        }
        catch (Exception ex)
        {
            this.familyName = System.Drawing.FontFamily.GenericSerif.Name;
        }
    }

    // ====================================================================
    // Creates the bitmap image.
    // ====================================================================
    private void GenerateImage()
    {
        // Create a new 32-bit bitmap image.
        Bitmap bitmap = new Bitmap(this.width, this.height, PixelFormat.Format32bppArgb);

        // Create a graphics object for drawing.
        Graphics g = Graphics.FromImage(bitmap);
        g.SmoothingMode = SmoothingMode.AntiAlias;
        Rectangle rect = new Rectangle(0, 0, this.width, this.height);

        // Fill in the background.
        HatchBrush hatchBrush = new HatchBrush(HatchStyle.SmallConfetti, Color.LightGray, Color.White);
        g.FillRectangle(hatchBrush, rect);

        // Set up the text font.
        SizeF size;
        float fontSize = rect.Height + 1;
        Font font;
        // Adjust the font size until the text fits within the image.
        do
        {
            fontSize--;
            font = new Font(this.familyName, fontSize, FontStyle.Bold);
            size = g.MeasureString(this.text, font);
        } while (size.Width > rect.Width);

        // Set up the text format.
        StringFormat format = new StringFormat();
        format.Alignment = StringAlignment.Center;
        format.LineAlignment = StringAlignment.Center;

        // Create a path using the text and warp it randomly.
        GraphicsPath path = new GraphicsPath();
        path.AddString(this.text, font.FontFamily, (int)font.Style, font.Size, 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);

        // Draw the text.
        hatchBrush = new HatchBrush(HatchStyle.LargeConfetti, Color.LightGray, Color.DarkGray);
        g.FillPath(hatchBrush, path);

        // Add some random noise.
        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);
        }

        // Clean up.
        font.Dispose();
        hatchBrush.Dispose();
        g.Dispose();

        // Set the image.
        this.image = bitmap;
    }
}

الآن نفذ البرنامج و كل شيئ من المفترض أن يعمل بشكل جيد كما في الشكل الموجود في أعلى الموضوع.

و يمكنك تحميل المشروع كاملاً من هنا:

captcha.zip (4.42 kb)

أحب أن انوه أن هذا المثال ينتج CAPTCHA بسيطة جداً تتكون من أرقام فقط، و الكود لإنتاج الأرقام موجود و من الممكن أن تغير فيها لكي ينتج ارقام و حروف أو حتى كلمات.

من الممكن بقليل من البحث في Google الوصول إلى User Controls جاهزة تقوم بالعمل كله و بشكل احترافي و مجاني.

 

أتمنى لكم التوفيق...

طلال السبيعي.

Del.icio.usDigg It!DZone It!Reddit

التصنيف: .NET , ASP.NET , C# , أمن المعلومات
البطاقات: , ,

اضف تعليق


(سيظهر Gravatar أيقونة)  

  Country flag

biuquote
  • تعليق
  • استعراض
Loading



Sign in