[C#] 第一次自己作 Captcha(驗證碼) 就上手(3)
2013-03-14
上一篇 [C#] 第一次自己作 Captcha(驗證碼) 就上手(2)
實作出來 Captcha 圖片..
有朋友過來問我說要怎麼做,我就繼續把這系列寫完..
首先,我會將認證是否符合產生出來的字放在server 端檢查..
透過Postback 驗證
畫面:
中間我圖片是做成base64 避免生出大量檔案..
接下來都寫在註解裡:
private string CurrentCaptcha
{ //存放在Session 中 get { return Session["CAPTCHA"].ToString(); } set { Session["CAPTCHA"] = value; }}
protected void Page_Load(object sender, EventArgs e)
{ //如果只是postback 就不更新 if (!IsPostBack) { //取一個新的GUID 然後取MD5 因為GUID只有到F 並取四碼 CurrentCaptcha = FormsAuthentication.HashPasswordForStoringInConfigFile(Guid.NewGuid().ToString(), "MD5").Substring(0, 4); Helper helper = new Helper();var result = helper.GetCaptcha(CurrentCaptcha, "Verdana", Server.MapPath("bk.jpg"), 95, 65, 22, 2);
Image1.Src = "data:image/" + GetImageFormat(result) + ";base64," + ImageToBase64(result);
}
}
/// <summary>/// 更新按下時 充新換Key/// </summary>/// <param name="sender"></param>/// <param name="e"></param>protected void btnRefresh_Click(object sender, EventArgs e)
{ ////取一個新的GUID 然後取MD5 因為GUID只有到F 並取四碼 CurrentCaptcha = FormsAuthentication.HashPasswordForStoringInConfigFile(Guid.NewGuid().ToString(), "MD5").Substring(0, 4); Helper helper = new Helper();var result = helper.GetCaptcha(CurrentCaptcha, "Verdana", Server.MapPath("bk.jpg"), 95, 65, 22, 2);
Image1.Src = "data:image/" + GetImageFormat(result) + ";base64," + ImageToBase64(result);
}
/// <summary>/// 自動判斷圖片格式/// </summary>/// <param name="img"></param>/// <returns></returns>public static System.Drawing.Imaging.ImageFormat GetImageFormat(Image img)
{ if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg)) return System.Drawing.Imaging.ImageFormat.Jpeg; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Bmp)) return System.Drawing.Imaging.ImageFormat.Bmp; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png)) return System.Drawing.Imaging.ImageFormat.Png; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Emf)) return System.Drawing.Imaging.ImageFormat.Emf; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Exif)) return System.Drawing.Imaging.ImageFormat.Exif; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Gif)) return System.Drawing.Imaging.ImageFormat.Gif; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Icon)) return System.Drawing.Imaging.ImageFormat.Icon; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.MemoryBmp)) return System.Drawing.Imaging.ImageFormat.MemoryBmp; if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Tiff)) return System.Drawing.Imaging.ImageFormat.Tiff; return System.Drawing.Imaging.ImageFormat.Wmf;}
/// <summary>/// 將 Image 物件轉 Base64/// Convert image to base64/// </summary>/// <param name="image"></param>/// <returns></returns>public string ImageToBase64(Bitmap image)
{ MemoryStream ms = new MemoryStream(); // 將圖片轉成 byte[] // Comvert image to byte[]image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] imageBytes = ms.ToArray(); // 將 byte[] 轉 base64 // byte to base64 string base64String = Convert.ToBase64String(imageBytes); return base64String;}
/// <summary>/// 按下確認後認證/// </summary>/// <param name="sender"></param>/// <param name="e"></param>protected void btnCheck_Click(object sender, EventArgs e)
{ //印出來是否正確lblResult.Text = (CurrentCaptcha.ToUpper() == txtCaptcha.Text.Trim().ToUpper()).ToString() + CurrentCaptcha;
}
透過 AJAX
首先,我會先建立一個 Captcha的 .aspx 或是 .ashx 專門產圖
實作方式可以參考 : [ASP.net] 用Response作Image 輸出,並可控制權限
CaptchaCreator.aspx:
using System;using System.Drawing.Imaging;using System.IO;using System.Web.Security;using RippleCaptcha;namespace TestRippleCaptcha{public partial class CaptchaCreator : System.Web.UI.Page
{private string CurrentCaptcha
{ get { return Session["CAPTCHA"].ToString(); } set { Session["CAPTCHA"] = value; }}
protected void Page_Load(object sender, EventArgs e)
{ CurrentCaptcha = FormsAuthentication.HashPasswordForStoringInConfigFile(Guid.NewGuid().ToString(), "MD5").Substring(0, 4); Helper helper=new Helper();var result = helper.GetCaptcha(CurrentCaptcha, "Verdana", Server.MapPath("bk.jpg"), 95, 65, 22, 7);
//設定 ContentType 為 jpg圖片 // Set the ContentType to jpg picture. Response.ContentType = "image/jpeg"; //注意這邊要用writefile 其中帶入圖片路徑byte[] data = null;
using (MemoryStream oMemoryStream = new MemoryStream())
{ //儲存圖片到 MemoryStream 物件,並且指定儲存影像之格式 //Save image to MemoryStream and set it to jpeg format.result.Save(oMemoryStream, ImageFormat.Jpeg);
//設定資料流位置 //Set stream position start from zerooMemoryStream.Position = 0;
//設定 buffer 長度 //Set buffer lengthdata = new byte[oMemoryStream.Length];
//將資料寫入 buffer //Wrire data to bufferoMemoryStream.Read(data, 0, Convert.ToInt32(oMemoryStream.Length));
//將所有緩衝區的資料寫入資料流 //Flush memory.oMemoryStream.Flush();
}
//將buffer 中的stream全部送出Response.BinaryWrite(data);
Response.Flush();
}
}
}
實作端:
HTML :
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestAjax.aspx.cs" Inherits="TestRippleCaptcha.TestAjax" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"><title></title>
<script src="http://code.jquery.com/jquery-1.8.0.min.js" type="text/javascript"></script>
</head>
<body>
<form id="form1" runat="server">
<div>
<img src="CaptchaCreator.aspx" id="imgCaptcha" />
<asp:TextBox ID="txtCaptcha" runat="server"></asp:TextBox>
<input type="button" id="input_Refresh" value="Refresh" />
<br />
<asp:Button ID="btnCheck" runat="server" Text="Check" OnClick="btnCheck_Click" />
<br />
<asp:Label ID="lblResult" runat="server" Text=""></asp:Label>
<script type="text/javascript">$('#input_Refresh').click(function () {
$('#imgCaptcha').attr('src', 'CaptchaCreator.aspx?' + RandomNumber(1, 9999));
});
function RandomNumber(min, max) { return Math.floor(Math.random() * (max - min + 1) + min);}
</script>
</div>
</form>
</body>
</html>
驗證依然在 Server 端..
using System;namespace TestRippleCaptcha{public partial class TestAjax : System.Web.UI.Page
{protected void Page_Load(object sender, EventArgs e)
{}
protected void btnCheck_Click(object sender, EventArgs e)
{ lblResult.Text = (Session["CAPTCHA"].ToString().ToUpper() == txtCaptcha.Text.Trim().ToUpper()).ToString();}
}
}
完整程式碼放在 Github : https://github.com/donma/RippleCaptcha
下載後直接可以跑..
