public class ValidateCodeHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "image/jpeg";
using (var img = new Bitmap(80, 25))
using (var g = Graphics.FromImage(img))
{
// 1. 背景填白
g.Clear(Color.White);
// 2. 畫邊框(寬高 -1 避免被背景覆蓋)
g.DrawRectangle(Pens.Black, 0, 0, img.Width - 1, img.Height - 1);
// 3. 畫雜訊線
DrawNoise(100, g, img);
// 4. 產生 4 碼驗證碼並寫入 Session
string code = GenerateCode(4);
context.Session["ValidateCode"] = code;
// 5. 畫驗證碼文字(刪除線字體增加辨識難度)
g.DrawString(code,
new Font("Arial", 14, FontStyle.Strikeout),
Brushes.Black,
new RectangleF(new Random().Next(20), new Random().Next(7), img.Width, img.Height));
// 6. 輸出 JPEG
img.Save(context.Response.OutputStream, ImageFormat.Jpeg);
}
}
private static readonly Random _rnd = new Random();
private void DrawNoise(int count, Graphics g, Image img)
{
for (int i = 0; i < count; i++)
{
int x = _rnd.Next(img.Width);
int y = _rnd.Next(img.Height);
g.DrawLine(Pens.Red, x, y, x + 2, y + 2);
}
}
private string GenerateCode(int length)
{
const string chars = "ASF2345WE5R9F3HMBCZ455K"; // 排除 1/l/o/O 等易混淆字元
char[] arr = chars.ToCharArray();
var sb = new StringBuilder();
for (int i = 0; i < length; i++)
sb.Append(arr[_rnd.Next(arr.Length)]);
return sb.ToString();
}
public bool IsReusable => false;
}
<img id="imgCode" src="ValidateCodeHandler.ashx" alt="驗證碼" style="cursor:pointer;" />
<a href="javascript:void(0);" onclick="$('#imgCode').attr('src', 'ValidateCodeHandler.ashx?' + Math.random());">看不清?換一張</a>
<br />
<input type="text" id="txtCode" />
<asp:Button ID="btnSubmit" runat="server" Text="送出" OnClick="btnSubmit_Click" />
protected void btnSubmit_Click(object sender, EventArgs e)
{
string userInput = txtCode.Text.Trim().ToUpper();
string serverCode = Session["ValidateCode"]?.ToString()?.ToUpper();
if (string.Equals(userInput, serverCode))
{
// 驗證通過
}
else
{
// 驗證失敗
}
}
TwistImage 正弦波位移演算法,大幅提升 OCR 識別難度。若專案允許引入 NuGet 套件,推薦使用 Captcha.NET、SkiaSharp 繪製更美觀、更安全的驗證碼,或直接整合 Google reCAPTCHA v3 / hCaptcha 以行為分析取代圖形辨識,兼顧安全性與使用者體驗。