Cách tạo Captcha đơn giản bằng ASP.NET

Captcha là một giải pháp hoàn hảo để chống spam khi đăng ký toàn khoản ở các trang web, các forum. Theo mình biết, có một số phần mềm tự động đăng ký tài khoản rồi post các bài viết spam ở các diễn đàn để quảng cáo hoăc với mục đích nào đó. Nhưng với captcha tự động thay đổi thì các phần mềm này sẽ phải bó tay.

Trong bài viết này, mình sẽ hướng dẫn các bạn tạo 1 captcha đơn giản cho trang web của mình thêm tính chuyên nghiệp.

Đầu tiên ở trang aspx bạn kéo vào các control như đoạn code sau:


<asp:UpdatePanel runat="server" ID="updatepanelcaptcha">
<ContentTemplate>
<asp:Image ID="captchaImage" runat="server" />
&nbsp;
<asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="~/Images/Web/reload.jpg"
OnClick="ImageButton1_Click" />
</ContentTemplate>
</asp:UpdatePanel>

Khi làm xong hết và chạy thì sẽ được như hình sau: Capture


Mình cho tất cả vào update panel để khi clink vào ImageButton1 nó sẽ thay đổi captcha và trang web không bị load lại.


Bạn vào trang aspx.cs và dán vào đoạn code sau:



//Trả về đường dẫn của tập tin hình.
public string CreateCaptcha()
{
const byte LENGTH = 5;
// chiều dài chuỗi để lấy các kí tự sẽ sử dụng cho captcha
const string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
using (Bitmap bmp = new Bitmap(120, 35))
{
using (Graphics g = Graphics.FromImage(bmp))
{
// Tạo nền cho ảnh dạng sóng
HatchBrush brush = new HatchBrush(HatchStyle.Percent80, Color.White, Color.Tan);
g.FillRegion(brush, g.Clip);
// Lưu chuỗi captcha trong quá trình tạo
StringBuilder strCaptcha = new StringBuilder();
Random rand = new Random();
float locationX = 3;
for (int i = 0; i < LENGTH; i++)
{
// Lấy kí tự ngẫu nhiên từ mảng chars
SolidBrush brushes = new SolidBrush(GetRandomColor());
string str = chars[rand.Next(chars.Length)].ToString();
strCaptcha.Append(str);
// Tạo font với tên font ngẫu nhiên chọn từ mảng fonts
Font font = new Font("Times New Roman", new Random().Next(14, 17), FontStyle.Bold);
// Lấy kích thước của kí tự
SizeF size = g.MeasureString(str, font);
// Vẽ kí tự đó ra ảnh tại vị trí tăng dần theo i, vị trí top ngẫu nhiên
g.DrawString(str, font,brushes, locationX, rand.Next(2, 10));
font.Dispose();
//định location X
locationX += size.Width + i;
}
// Lưu captcha vào session
Session["captcha"] = strCaptcha.ToString();
// Ghi ảnh trực tiếp ra luồng xuất theo định dạng gif
//Response.ContentType = "image/GIF";4
int numRandom = new Random().Next(1, 3000);
string imgFile = "captcha" + numRandom + ".jpg";
string directoryCaptcha = "~/Images/Captcha";
// Kiểm tra thư mục đã tồn tại
if (!Directory.Exists(Server.MapPath(directoryCaptcha)))
{
Directory.CreateDirectory(Server.MapPath(directoryCaptcha));
}
//lấy thông tin thư mục
DirectoryInfo direcInfo = new DirectoryInfo(Server.MapPath(directoryCaptcha));
foreach (FileInfo file in direcInfo.GetFiles(".jpg"))
{
try
{
//Xóa tất cả các tập tin hình trong thư mục hiện tại
file.Delete();
}
catch { }
}
bmp.Save(Server.MapPath(directoryCaptcha + imgFile));
return directoryCaptcha + imgFile;
}
}
}
int rrandom = 0;
int grandom = 0;
int brandom = 0;


public Color GetRandomColor()
{
Random rnd = new Random();
int ri = rnd.Next(255);
if (ri == rrandom){
ri = rnd.Next(255);
}
else{
rrandom = ri;
}
int gi = rnd.Next(255);
if (gi == grandom){
gi = rnd.Next(255);
}
else{
grandom = gi;
}
int bi = rnd.Next(255);
if (bi == brandom){
bi = rnd.Next(255);
}
else{
brandom = bi;
}
byte r = Convert.ToByte(ri);
byte g = Convert.ToByte(gi);
byte b = Convert.ToByte(bi);
return Color.FromArgb(r, g, b);
}


Trong sự kiện pageload bạn duyệt tất cả hình có trong thư mục Images và xóa nó đi rồi tạo captcha mới. Nếu không làm như vậy mỗi lần hàm CreateCaptcha được gọi là 1 hình được tạo ra. Nhiều lần như vậy sẽ tốn dung lượng lưu trữ.



if (!IsPostBack)
{
DirectoryInfo dr = new DirectoryInfo(Server.MapPath("~/Images"));
foreach (FileInfo f in dr.GetFiles())
{
f.Delete();
}
captchaImage.ImageUrl = CreateCaptcha();
}


Tương tự khi clink vào ImageButton1 để load lại captcha ta cũng làm công việc đó.



DirectoryInfo dr = new DirectoryInfo(Server.MapPath("~/Images"));
foreach (FileInfo f in dr.GetFiles())
{
f.Delete();
}
captchaImage.ImageUrl = CreateCaptcha();


Vậy là xong, bạn hãy chạy thử và xem kết quả.

Để hiểu rõ phương pháp này bạn cần biết cách sử dụng phương thức đồ họa GDI+ trong C#. Mình cũng không thể giải thích cặn kẽ từng dòng code được.
Chúc các bạn thành công!

2 nhận xét:

hoangle nói...

Bài viết rất hay, cảm ơn bạn nhiều
qivana

Thiết kế website giá rẻ nói...

bài viết hay quá.thanks nhé