一、驗證碼簡介
驗證碼功能一般是用於防止大量註冊的,不少網站為了防止使用者利用機器人自動註冊、登入、灌水,都採用了驗證碼技術。所謂驗證碼,就是將一串隨機產生的數字或字母或符號或文字,產生一幅圖片, 圖片裡加上一些幹擾象素(防止OCR),由使用者肉眼識別其中的驗證碼資訊,輸入表單提交網站驗證,驗證成功後才能使用某項功能。
常見的驗證碼有如下幾種:
1、純數字驗證碼,一般為四位隨機數字;
2、數字+字母驗證碼,一般從數字(0~9)和字母(A~Z和a~z)中隨機抽出幾個字元組成;
3、漢字驗證碼,相對而言,這種驗證碼比較少見一點,實現起來也相對複雜一些,但在不少網站中還是可以看到的;
二、驗證碼的實現
1、純數字驗證碼的實現
純數字驗證碼的實現相對比較簡單,可通過以下兩種方法來實現
(1)使用隨機數方式,代碼如下:
private String GetRandomint(int codeCount)<br /> {<br /> Random random = new Random();<br /> string min = "";<br /> string max = "";<br /> for (int i = 0; i < codeCount; i++)<br /> {<br /> min +="1";<br /> max+="9";<br /> }<br /> return (random.Next(Convert.ToInt32(min),Convert.ToInt32(max)).ToString());<br /> }
(2)使用隨機組合方式,代碼如下:
private string CreateRandomCode(int codeCount)<br /> {<br /> string allChar = "0,1,2,3,4,5,6,7,8,9";<br /> string[] allCharArray = allChar.Split(',');<br /> string randomCode = "";<br /> int temp = -1;<br /> Random rand = new Random();<br /> for (int i = 0; i < codeCount; i++)<br /> {<br /> if (temp != -1)<br /> {<br /> rand = new Random(i * temp * ((int)DateTime.Now.Ticks));<br /> }<br /> int t = rand.Next(9);<br /> if (temp == t)<br /> {<br /> return CreateRandomCode(codeCount);<br /> }<br /> temp = t;<br /> randomCode += allCharArray[t];<br /> }<br /> return randomCode;<br /> }
2、數字+字母驗證碼的實現,代碼如下:
private string CreateRandomCode(int codeCount)<br /> {<br /> string allChar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";<br /> string[] allCharArray = allChar.Split(',');<br /> string randomCode = "";<br /> int temp = -1;<br /> Random rand = new Random();<br /> for (int i = 0; i < codeCount; i++)<br /> {<br /> if (temp != -1)<br /> {<br /> rand = new Random(i * temp * ((int)DateTime.Now.Ticks));<br /> }<br /> int t = rand.Next(61);<br /> if (temp == t)<br /> {<br /> return CreateRandomCode(codeCount);<br /> }<br /> temp = t;<br /> randomCode += allCharArray[t];<br /> }<br /> return randomCode;<br /> }<br />
3、漢字驗證碼的實現,代碼如下:
/**/<br /> /* 此函數在漢字編碼範圍內隨機建立含兩個元素的十六進位位元組數組,每個位元組數組代表一個漢字,並將<br /> 四個位元組數組儲存在object數組中。<br /> 參數:strlength,代表需要產生的漢字個數<br /> */<br /> public static object[] CreateRegionCode(int strlength)<br /> {<br /> //定義一個字串數組儲存漢字編碼的組成元素<br /> string[] rBase = new String[16] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };<br /> Random rnd = new Random();<br /> //定義一個object數組用來<br /> object[] bytes = new object[strlength];</p><p> /**/<br /> /*每迴圈一次產生一個含兩個元素的十六進位位元組數組,並將其放入bject數組中<br /> 每個漢字有四個區位碼組成<br /> 區位碼第1位和區位碼第2位作為位元組數組第一個元素<br /> 區位碼第3位和區位碼第4位作為位元組數組第二個元素<br /> */<br /> for (int i = 0; i < strlength; i++)<br /> {<br /> //區位碼第1位<br /> int r1 = rnd.Next(11, 14);<br /> string str_r1 = rBase[r1].Trim();</p><p> //區位碼第2位<br /> rnd = new Random(r1 * unchecked((int)DateTime.Now.Ticks) + i);//更換隨機數發生器的種子避免產生重複值<br /> int r2;<br /> if (r1 == 13)<br /> {<br /> r2 = rnd.Next(0, 7);<br /> }<br /> else<br /> {<br /> r2 = rnd.Next(0, 16);<br /> }<br /> string str_r2 = rBase[r2].Trim();</p><p> //區位碼第3位<br /> rnd = new Random(r2 * unchecked((int)DateTime.Now.Ticks) + i);<br /> int r3 = rnd.Next(10, 16);<br /> string str_r3 = rBase[r3].Trim();</p><p> //區位碼第4位<br /> rnd = new Random(r3 * unchecked((int)DateTime.Now.Ticks) + i);<br /> int r4;<br /> if (r3 == 10)<br /> {<br /> r4 = rnd.Next(1, 16);<br /> }<br /> else if (r3 == 15)<br /> {<br /> r4 = rnd.Next(0, 15);<br /> }<br /> else<br /> {<br /> r4 = rnd.Next(0, 16);<br /> }<br /> string str_r4 = rBase[r4].Trim();</p><p> //定義兩個位元組變數儲存產生的隨機漢字區位碼<br /> byte byte1 = Convert.ToByte(str_r1 + str_r2, 16);<br /> byte byte2 = Convert.ToByte(str_r3 + str_r4, 16);<br /> //將兩個位元組變數儲存在位元組數組中<br /> byte[] str_r = new byte[] { byte1, byte2 };</p><p> //將產生的一個漢字的位元組數組放入object數組中<br /> bytes.SetValue(str_r, i);<br /> }<br /> return bytes;<br /> }
三、具體執行個體
前台代碼display.aspx
<body><br /> <form id="form1" runat="server"><br /> <div><br /> <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><br /> <asp:Image ID="Image1" runat="server" ImageUrl="png.aspx" /><br /><br /> <br /><br /> <asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="Button" /><br /> <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged"><br /> <asp:ListItem Value="3">預設</asp:ListItem><br /> <asp:ListItem Value="1">文字</asp:ListItem><br /> <asp:ListItem Value="2">數字</asp:ListItem><br /> <asp:ListItem Value="3">混合</asp:ListItem><br /> </asp:DropDownList></div><br /> </form><br /></body>
後台代碼display.cs
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)<br /> {<br /> switch (DropDownList1.SelectedValue)<br /> {<br /> case "1":<br /> Image1.ImageUrl = "png.aspx?aa=1";<br /> break;<br /> case "2":<br /> Image1.ImageUrl = "png.aspx?aa=2";<br /> break;<br /> case "3":<br /> Image1.ImageUrl = "png.aspx?aa=3";<br /> break;<br /> }<br /> }<br /> protected void Button2_Click(object sender, EventArgs e)<br /> {<br /> if (TextBox1.Text == Session["gif"].ToString())<br /> Response.Write("OK,正確");<br /> else<br /> Response.Write("驗證碼不符合");<br /> }
後台代碼png.cs
public partial class png : System.Web.UI.Page<br /> {<br /> protected void Page_Load(object sender, EventArgs e)<br /> {<br /> switch (Request.QueryString["aa"])<br /> {<br /> case "1":<br /> gif = stxt(10);<br /> Session["gif"] = stxt(10);<br /> break;<br /> case "2":<br /> gif = GetRandomint(4);<br /> Session["gif"] = GetRandomint(4);<br /> break;<br /> case "3":<br /> gif = CreateRandomCode(4);<br /> Session["gif"] = CreateRandomCode(4);<br /> break;<br /> default:<br /> gif = CreateRandomCode(4);<br /> Session["gif"] = CreateRandomCode(4);<br /> break;<br /> }<br /> CreateImage(Session["gif"].ToString());<br /> }</p><p> private String GetRandomint(int codeCount)<br /> {<br /> Random random = new Random();<br /> string min = "";<br /> string max = "";<br /> for (int i = 0; i < codeCount; i++)<br /> {<br /> min +="1";<br /> max+="9";<br /> }<br /> return (random.Next(Convert.ToInt32(min),Convert.ToInt32(max)).ToString());<br /> }<br /> /**/<br /> /*<br /> 此函數在漢字編碼範圍內隨機建立含兩個元素的十六進位位元組數組,每個位元組數組代表一個漢字,並將<br /> 四個位元組數組儲存在object數組中。<br /> 參數:strlength,代表需要產生的漢字個數<br /> */<br /> public static object[] CreateRegionCode(int strlength)<br /> {<br /> //定義一個字串數組儲存漢字編碼的組成元素<br /> string[] rBase = new String[16] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };<br /> Random rnd = new Random();<br /> //定義一個object數組用來<br /> object[] bytes = new object[strlength];</p><p> /**/<br /> /*每迴圈一次產生一個含兩個元素的十六進位位元組數組,並將其放入bject數組中<br /> 每個漢字有四個區位碼組成<br /> 區位碼第1位和區位碼第2位作為位元組數組第一個元素<br /> 區位碼第3位和區位碼第4位作為位元組數組第二個元素<br /> */<br /> for (int i = 0; i < strlength; i++)<br /> {<br /> //區位碼第1位<br /> int r1 = rnd.Next(11, 14);<br /> string str_r1 = rBase[r1].Trim();</p><p> //區位碼第2位<br /> rnd = new Random(r1 * unchecked((int)DateTime.Now.Ticks) + i);//更換隨機數發生器的種子避免產生重複值<br /> int r2;<br /> if (r1 == 13)<br /> {<br /> r2 = rnd.Next(0, 7);<br /> }<br /> else<br /> {<br /> r2 = rnd.Next(0, 16);<br /> }<br /> string str_r2 = rBase[r2].Trim();</p><p> //區位碼第3位<br /> rnd = new Random(r2 * unchecked((int)DateTime.Now.Ticks) + i);<br /> int r3 = rnd.Next(10, 16);<br /> string str_r3 = rBase[r3].Trim();</p><p> //區位碼第4位<br /> rnd = new Random(r3 * unchecked((int)DateTime.Now.Ticks) + i);<br /> int r4;<br /> if (r3 == 10)<br /> {<br /> r4 = rnd.Next(1, 16);<br /> }<br /> else if (r3 == 15)<br /> {<br /> r4 = rnd.Next(0, 15);<br /> }<br /> else<br /> {<br /> r4 = rnd.Next(0, 16);<br /> }<br /> string str_r4 = rBase[r4].Trim();</p><p> //定義兩個位元組變數儲存產生的隨機漢字區位碼<br /> byte byte1 = Convert.ToByte(str_r1 + str_r2, 16);<br /> byte byte2 = Convert.ToByte(str_r3 + str_r4, 16);<br /> //將兩個位元組變數儲存在位元組數組中<br /> byte[] str_r = new byte[] { byte1, byte2 };</p><p> //將產生的一個漢字的位元組數組放入object數組中<br /> bytes.SetValue(str_r, i);<br /> }<br /> return bytes;<br /> }<br /> private string stxt(int num)<br /> {<br /> Encoding gb = Encoding.GetEncoding("gb2312");</p><p> //調用函數產生10個隨機中文漢字編碼<br /> object[] bytes = CreateRegionCode(num);<br /> string strtxt = "";</p><p> //根據漢字編碼的位元組數組解碼出中文漢字<br /> for (int i = 0; i < num; i++)<br /> {<br /> strtxt += gb.GetString((byte[])Convert.ChangeType(bytes[i], typeof(byte[])));<br /> }<br /> return strtxt;<br /> }<br /> /// <summary><br /> /// 這個是使用字母,數字混合<br /> /// </summary><br /> /// <param name="VcodeNum"></param><br /> /// <returns></returns><br /> private string CreateRandomCode(int codeCount)<br /> {<br /> string allChar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";<br /> string[] allCharArray = allChar.Split(',');<br /> string randomCode = "";<br /> int temp = -1;<br /> Random rand = new Random();<br /> for (int i = 0; i < codeCount; i++)<br /> {<br /> if (temp != -1)<br /> {<br /> rand = new Random(i * temp * ((int)DateTime.Now.Ticks));<br /> }<br /> int t = rand.Next(61);<br /> if (temp == t)<br /> {<br /> return CreateRandomCode(codeCount);<br /> }<br /> temp = t;<br /> randomCode += allCharArray[t];<br /> }<br /> return randomCode;<br /> }</p><p> private void CreateImage(string checkCode)<br /> {<br /> int iwidth = (int)(checkCode.Length * 20);<br /> System.Drawing.Bitmap image = new System.Drawing.Bitmap(iwidth, 25);<br /> Graphics g = Graphics.FromImage(image);<br /> Font f = new System.Drawing.Font("Arial", 10, System.Drawing.FontStyle.Bold);<br /> Brush b = new System.Drawing.SolidBrush(Color.White);<br /> //g.FillRectangle(new System.Drawing.SolidBrush(Color.Blue),0,0,image.Width, image.Height);<br /> g.Clear(Color.Black);<br /> g.DrawString(checkCode, f, b, 3, 3);<br /> Pen blackPen = new Pen(Color.Black, 0);<br /> Random rand = new Random();<br /> //for (int i=0;i<5;i++)<br /> //{<br /> // int y = rand.Next(image.Height);<br /> // g.DrawLine(blackPen,0,y,image.Width,y);<br /> //}<br /> System.IO.MemoryStream ms = new System.IO.MemoryStream();<br /> image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);<br /> Response.ClearContent();<br /> Response.ContentType = "image/Jpeg";<br /> Response.BinaryWrite(ms.ToArray());<br /> g.Dispose();<br /> image.Dispose();<br /> }<br /> }
四、展示
驗證碼數字
驗證碼數字+字母
驗證碼漢字