asp.net实现网站验证码功能

一、验证码简介

验证码功能一般是用于防止批量注册的,不少网站为了防止用户利用机器人自动注册、登录、灌水,都采用了验证码技术。所谓验证码,就是将一串随机产生的数字或字母或符号或文字,生成一幅图片, 图片里加上一些干扰象素(防止OCR),由用户肉眼识别其中的验证码信息,输入表单提交网站验证,验证成功后才能使用某项功能。

常见的验证码有如下几种:

1、纯数字验证码,一般为四位随机数字;

2、数字+字母验证码,一般从数字(0~9)和字母(A~Z和a~z)中随机抽出几个字符组成;

3、汉字验证码,相对而言,这种验证码比较少见一点,实现起来也相对复杂一些,但在不少网站中还是可以看到的;

二、验证码的实现

1、纯数字验证码的实现

纯数字验证码的实现相对比较简单,可通过以下两种方法来实现

(1)使用随机数方式,代码如下:

  1. private String GetRandomint(int codeCount)   
  2. {   
  3.     Random random = new Random();   
  4.     string min = "";   
  5.     string max = "";   
  6.     for (int i = 0; i < codeCount; i++)   
  7.     {   
  8.         min +="1";   
  9.         max+="9";   
  10.     }   
  11.         return (random.Next(Convert.ToInt32(min),Convert.ToInt32(max)).ToString());   
  12. }  

 

(2)使用随机组合方式,代码如下:

  1. private string CreateRandomCode(int codeCount)   
  2. {   
  3.     string allChar = "0,1,2,3,4,5,6,7,8,9";    
  4.     string[] allCharArray = allChar.Split(',');    
  5.     string randomCode = "";    
  6.     int temp = -1;    
  7.     Random rand = new Random();    
  8.     for (int i = 0; i < codeCount; i++)    
  9.     {    
  10.         if (temp != -1)    
  11.         {    
  12.             rand = new Random(i * temp * ((int)DateTime.Now.Ticks));    
  13.         }    
  14.         int t = rand.Next(9);    
  15.         if (temp == t)    
  16.         {    
  17.             return CreateRandomCode(codeCount);    
  18.         }    
  19.         temp = t;    
  20.         randomCode += allCharArray[t];    
  21.     }    
  22.     return randomCode;   
  23. }  

 

2、数字+字母验证码的实现,代码如下:

  1. private string CreateRandomCode(int codeCount)   
  2. {   
  3.     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";    
  4.     string[] allCharArray = allChar.Split(',');    
  5.     string randomCode = "";    
  6.     int temp = -1;    
  7.     Random rand = new Random();    
  8.     for (int i = 0; i < codeCount; i++)    
  9.     {    
  10.         if (temp != -1)    
  11.         {    
  12.             rand = new Random(i * temp * ((int)DateTime.Now.Ticks));    
  13.         }    
  14.         int t = rand.Next(61);    
  15.         if (temp == t)    
  16.         {    
  17.             return CreateRandomCode(codeCount);    
  18.         }    
  19.         temp = t;    
  20.         randomCode += allCharArray[t];    
  21.     }    
  22.     return randomCode;   
  23. }  
 

 

 3、汉字验证码的实现,代码如下:

  1. /**/  
  2. /* 此函数在汉字编码范围内随机创建含两个元素的十六进制字节数组,每个字节数组代表一个汉字,并将   
  3. 四个字节数组存储在object数组中。   
  4. 参数:strlength,代表需要产生的汉字个数   
  5. */  
  6.     public static object[] CreateRegionCode(int strlength)   
  7.     {   
  8.         //定义一个字符串数组储存汉字编码的组成元素    
  9.         string[] rBase = new String[16] { "0""1""2""3""4""5""6""7""8""9""a""b""c""d""e""f" };   
  10.         Random rnd = new Random();   
  11.         //定义一个object数组用来    
  12.         object[] bytes = new object[strlength];   
  13.   
  14.         /**/  
  15.         /*每循环一次产生一个含两个元素的十六进制字节数组,并将其放入bject数组中   
  16.      每个汉字有四个区位码组成   
  17.      区位码第1位和区位码第2位作为字节数组第一个元素   
  18.      区位码第3位和区位码第4位作为字节数组第二个元素   
  19.     */  
  20.         for (int i = 0; i < strlength; i++)   
  21.         {   
  22.             //区位码第1位    
  23.             int r1 = rnd.Next(11, 14);   
  24.             string str_r1 = rBase[r1].Trim();   
  25.   
  26.             //区位码第2位    
  27.             rnd = new Random(r1 * unchecked((int)DateTime.Now.Ticks) + i);//更换随机数发生器的种子避免产生重复值    
  28.             int r2;   
  29.             if (r1 == 13)   
  30.             {   
  31.                 r2 = rnd.Next(0, 7);   
  32.             }   
  33.             else  
  34.             {   
  35.                 r2 = rnd.Next(0, 16);   
  36.             }   
  37.             string str_r2 = rBase[r2].Trim();   
  38.   
  39.             //区位码第3位    
  40.             rnd = new Random(r2 * unchecked((int)DateTime.Now.Ticks) + i);   
  41.             int r3 = rnd.Next(10, 16);   
  42.             string str_r3 = rBase[r3].Trim();   
  43.   
  44.             //区位码第4位    
  45.             rnd = new Random(r3 * unchecked((int)DateTime.Now.Ticks) + i);   
  46.             int r4;   
  47.             if (r3 == 10)   
  48.             {   
  49.                 r4 = rnd.Next(1, 16);   
  50.             }   
  51.             else if (r3 == 15)   
  52.             {   
  53.                 r4 = rnd.Next(0, 15);   
  54.             }   
  55.             else  
  56.             {   
  57.                 r4 = rnd.Next(0, 16);   
  58.             }   
  59.             string str_r4 = rBase[r4].Trim();   
  60.   
  61.             //定义两个字节变量存储产生的随机汉字区位码    
  62.             byte byte1 = Convert.ToByte(str_r1 + str_r2, 16);   
  63.             byte byte2 = Convert.ToByte(str_r3 + str_r4, 16);   
  64.             //将两个字节变量存储在字节数组中    
  65.             byte[] str_r = new byte[] { byte1, byte2 };   
  66.   
  67.             //将产生的一个汉字的字节数组放入object数组中    
  68.             bytes.SetValue(str_r, i);   
  69.         }   
  70.         return bytes;   
  71.     }  
 

 

 三、具体实例

前台代码display.aspx

  1. <body>   
  2.     <form id="form1" runat="server">   
  3.     <div>   
  4.        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>   
  5.         <asp:Image ID="Image1" runat="server" ImageUrl="png.aspx" /><br />   
  6.         <br />   
  7.        <asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="Button" />   
  8.         <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">   
  9.             <asp:ListItem Value="3">默认</asp:ListItem>   
  10.             <asp:ListItem Value="1">文字</asp:ListItem>   
  11.             <asp:ListItem Value="2">数字</asp:ListItem>   
  12.             <asp:ListItem Value="3">混合</asp:ListItem>   
  13.         </asp:DropDownList></div>   
  14.     </form>   
  15. </body>  
 

 

 后台代码display.cs

  1. protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)   
  2. {   
  3.     switch (DropDownList1.SelectedValue)   
  4.     {   
  5.         case "1":   
  6.             Image1.ImageUrl = "png.aspx?aa=1";   
  7.             break;   
  8.         case "2":   
  9.             Image1.ImageUrl = "png.aspx?aa=2";   
  10.             break;   
  11.         case "3":   
  12.             Image1.ImageUrl = "png.aspx?aa=3";   
  13.             break;   
  14.     }   
  15. }   
  16. protected void Button2_Click(object sender, EventArgs e)   
  17. {   
  18.     if (TextBox1.Text == Session["gif"].ToString())   
  19.         Response.Write("OK,正确");   
  20.     else  
  21.         Response.Write("验证码不符合");   
  22. }  

 

后台代码png.cs

  1. public partial class png : System.Web.UI.Page   
  2. {            
  3.     protected void Page_Load(object sender, EventArgs e)   
  4.     {   
  5.         switch (Request.QueryString["aa"])   
  6.         {   
  7.             case "1":   
  8.                 gif = stxt(10);   
  9.                 Session["gif"] = stxt(10);   
  10.                 break;   
  11.             case "2":   
  12.                 gif = GetRandomint(4);   
  13.                 Session["gif"] = GetRandomint(4);   
  14.                 break;   
  15.             case "3":   
  16.                 gif = CreateRandomCode(4);   
  17.                 Session["gif"] = CreateRandomCode(4);   
  18.                 break;   
  19.             default:   
  20.                 gif = CreateRandomCode(4);   
  21.                 Session["gif"] = CreateRandomCode(4);   
  22.                 break;   
  23.         }   
  24.         CreateImage(Session["gif"].ToString());   
  25.     }   
  26.   
  27.     private String GetRandomint(int codeCount)   
  28.     {   
  29.         Random random = new Random();   
  30.         string min = "";   
  31.         string max = "";   
  32.         for (int i = 0; i < codeCount; i++)   
  33.         {   
  34.             min +="1";   
  35.             max+="9";   
  36.         }   
  37.             return (random.Next(Convert.ToInt32(min),Convert.ToInt32(max)).ToString());   
  38.     }   
  39.     /**/  
  40.     /*   
  41. 此函数在汉字编码范围内随机创建含两个元素的十六进制字节数组,每个字节数组代表一个汉字,并将   
  42. 四个字节数组存储在object数组中。   
  43. 参数:strlength,代表需要产生的汉字个数   
  44. */  
  45.     public static object[] CreateRegionCode(int strlength)   
  46.     {   
  47.         //定义一个字符串数组储存汉字编码的组成元素    
  48.         string[] rBase = new String[16] { "0""1""2""3""4""5""6""7""8""9""a""b""c""d""e""f" };   
  49.         Random rnd = new Random();   
  50.         //定义一个object数组用来    
  51.         object[] bytes = new object[strlength];   
  52.   
  53.         /**/  
  54.         /*每循环一次产生一个含两个元素的十六进制字节数组,并将其放入bject数组中   
  55.      每个汉字有四个区位码组成   
  56.      区位码第1位和区位码第2位作为字节数组第一个元素   
  57.      区位码第3位和区位码第4位作为字节数组第二个元素   
  58.     */  
  59.         for (int i = 0; i < strlength; i++)   
  60.         {   
  61.             //区位码第1位    
  62.             int r1 = rnd.Next(11, 14);   
  63.             string str_r1 = rBase[r1].Trim();   
  64.   
  65.             //区位码第2位    
  66.             rnd = new Random(r1 * unchecked((int)DateTime.Now.Ticks) + i);//更换随机数发生器的种子避免产生重复值    
  67.             int r2;   
  68.             if (r1 == 13)   
  69.             {   
  70.                 r2 = rnd.Next(0, 7);   
  71.             }   
  72.             else  
  73.             {   
  74.                 r2 = rnd.Next(0, 16);   
  75.             }   
  76.             string str_r2 = rBase[r2].Trim();   
  77.   
  78.             //区位码第3位    
  79.             rnd = new Random(r2 * unchecked((int)DateTime.Now.Ticks) + i);   
  80.             int r3 = rnd.Next(10, 16);   
  81.             string str_r3 = rBase[r3].Trim();   
  82.   
  83.             //区位码第4位    
  84.             rnd = new Random(r3 * unchecked((int)DateTime.Now.Ticks) + i);   
  85.             int r4;   
  86.             if (r3 == 10)   
  87.             {   
  88.                 r4 = rnd.Next(1, 16);   
  89.             }   
  90.             else if (r3 == 15)   
  91.             {   
  92.                 r4 = rnd.Next(0, 15);   
  93.             }   
  94.             else  
  95.             {   
  96.                 r4 = rnd.Next(0, 16);   
  97.             }   
  98.             string str_r4 = rBase[r4].Trim();   
  99.   
  100.             //定义两个字节变量存储产生的随机汉字区位码    
  101.             byte byte1 = Convert.ToByte(str_r1 + str_r2, 16);   
  102.             byte byte2 = Convert.ToByte(str_r3 + str_r4, 16);   
  103.             //将两个字节变量存储在字节数组中    
  104.             byte[] str_r = new byte[] { byte1, byte2 };   
  105.   
  106.             //将产生的一个汉字的字节数组放入object数组中    
  107.             bytes.SetValue(str_r, i);   
  108.         }   
  109.         return bytes;   
  110.     }   
  111.     private string stxt(int num)   
  112.     {   
  113.         Encoding gb = Encoding.GetEncoding("gb2312");   
  114.   
  115.         //调用函数产生10个随机中文汉字编码    
  116.         object[] bytes = CreateRegionCode(num);   
  117.         string strtxt = "";   
  118.   
  119.         //根据汉字编码的字节数组解码出中文汉字    
  120.         for (int i = 0; i < num; i++)   
  121.         {   
  122.             strtxt += gb.GetString((byte[])Convert.ChangeType(bytes[i], typeof(byte[])));   
  123.         }   
  124.         return strtxt;   
  125.     }   
  126.     /// <summary>   
  127.     /// 这个是使用字母,数字混合   
  128.     /// </summary>   
  129.     /// <param name="VcodeNum"></param>   
  130.     /// <returns></returns>   
  131.     private string CreateRandomCode(int codeCount)   
  132.     {   
  133.         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";   
  134.         string[] allCharArray = allChar.Split(',');   
  135.         string randomCode = "";   
  136.         int temp = -1;   
  137.         Random rand = new Random();   
  138.         for (int i = 0; i < codeCount; i++)   
  139.         {   
  140.             if (temp != -1)   
  141.             {   
  142.                 rand = new Random(i * temp * ((int)DateTime.Now.Ticks));   
  143.             }   
  144.             int t = rand.Next(61);   
  145.             if (temp == t)   
  146.             {   
  147.                 return CreateRandomCode(codeCount);   
  148.             }   
  149.             temp = t;   
  150.             randomCode += allCharArray[t];   
  151.         }   
  152.         return randomCode;   
  153.     }   
  154.   
  155.     private void CreateImage(string checkCode)   
  156.     {   
  157.         int iwidth = (int)(checkCode.Length * 20);   
  158.         System.Drawing.Bitmap image = new System.Drawing.Bitmap(iwidth, 25);   
  159.         Graphics g = Graphics.FromImage(image);   
  160.         Font f = new System.Drawing.Font("Arial", 10, System.Drawing.FontStyle.Bold);   
  161.         Brush b = new System.Drawing.SolidBrush(Color.White);   
  162.         //g.FillRectangle(new System.Drawing.SolidBrush(Color.Blue),0,0,image.Width, image.Height);       
  163.         g.Clear(Color.Black);   
  164.         g.DrawString(checkCode, f, b, 3, 3);   
  165.         Pen blackPen = new Pen(Color.Black, 0);   
  166.         Random rand = new Random();   
  167.         //for (int i=0;i<5;i++)       
  168.         //{           
  169.         //    int y = rand.Next(image.Height);     
  170.         //    g.DrawLine(blackPen,0,y,image.Width,y);    
  171.         //}           
  172.         System.IO.MemoryStream ms = new System.IO.MemoryStream();   
  173.         image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);   
  174.         Response.ClearContent();   
  175.         Response.ContentType = "image/Jpeg";   
  176.         Response.BinaryWrite(ms.ToArray());   
  177.         g.Dispose();   
  178.         image.Dispose();   
  179.     }   
  180. }  

 

四、效果图展示
验证码数字

验证码数字+字母


 验证码汉字

posted @ 2009-02-26 00:13  怪_怪  阅读(340)  评论(0编辑  收藏  举报