• 一个GG/MM的彩色验证码图片(C#)


    1、为什么要加验证码?

    因为加了验证码可以防御别人攻击你的网站,举个例子:别人可以用webbrowser控件做一个模拟浏览器,并且模拟提交表单(模拟填写表单资料和点击提交按钮),那么你的服务器必须接收这些表单传过来的值,并且做判断,是否正确。这样一来,别人可以无限占用你的服务器资源,而且账号密码都不安全,万一被别人搞个循环1个1个账号轮询的话,很有可能让别人破解了你的资料信息,所以安全性稍微高点的网站登录都有彩色图片验证码。

    2、为什么彩色验证码图片可以防御别人的攻击?

    因为当别人用轮询技术模拟登录的时候,他并不知道你的验证码是什么,也获取不到,因为这是一张图片,电脑并不能识别里面的数字是什么(除非破解验证码里面的干扰,再利用相关的图片识别技术有可能读出验证码,这里先不扯这个)。读不出验证码就没有机会轮询访问了,当然我们后台判断的时候一定要先判断验证码是否正确,以防止占用服务器资源。

    3、随机数 Code

     ①数字随机数

     1         /// <summary>
     2         /// 数字随机数
     3         /// </summary>
     4         /// <returns></returns>
     5         private string GetRndNum()
     6         {
     7             string code = string.Empty;
     8             Random random = new Random();
     9             for (int i = 0; i < 4; i++)
    10             {
    11                 code = code + random.Next(9).ToString();
    12             }
    13             return code;
    14         }

    ②字符串随机数

     1         /// <summary>
     2         /// 字符串验证码
     3         /// </summary>
     4         /// <returns></returns>
     5         private string GetRndStr()
     6         {
     7             string Vchar = "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";
     8             string[] VcArray = Vchar.Split(',');
     9             string checkCode = string.Empty;
    10             Random rand = new Random();
    11             for (int i = 0; i < 4; i++)
    12             {
    13                 rand = new Random(unchecked((int)DateTime.Now.Ticks));//为了得到不同的随机序列
    14                 int t = rand.Next(VcArray.Length);// The exclusive upper bound of the random number to be generated. maxValue must be greater than or equal to zero,下标从0开始
    15                 checkCode += VcArray[t];
    16             }
    17             return checkCode;
    18         }

    ③中文随机数

     1         /// <summary>
     2         /// 随机中文码
     3         /// </summary>
     4         /// <returns></returns>
     5         private string GetRndCh()
     6         {
     7             System.Text.Encoding gb = System.Text.Encoding.Default;//获取GB2312编码页(表)
     8             object[] bytes = CreateRegionCode(4);//调用函数产生4个随机中文汉字编码
     9             string[] str = new string[4];
    10             System.Text.StringBuilder sb = new System.Text.StringBuilder();
    11             for (int i = 0; i < 4; i++)
    12             {
    13                 //根据汉字编码的字节数组解码出中文汉字
    14                 str[i] = gb.GetString((byte[])Convert.ChangeType(bytes[i], typeof(byte[])));
    15                 sb.Append( str[i].ToString());
    16             }
    17             return sb.ToString ();
    18         }        
    19 
    20 
    21         /// <summary>
    22         /// 产生随机中文汉字编码
    23         /// </summary>
    24         /// <param name="strlength"></param>
    25         /// <returns></returns>
    26         private static object[] CreateRegionCode(int strlength)
    27         {
    28             //定义一个字符串数组储存汉字编码的组成元素
    29             string[] rBase = new String[16] { "0""1""2""3""4""5""6""7""8""9""a""b""c""d""e""f" }; 
    30             Random rnd = new Random();
    31             object[] bytes = new object[strlength];
    32 
    33             for (int i = 0; i < strlength; i++)
    34             {
    35                 //区位码第1位
    36                 int r1 = rnd.Next(1114);
    37                 string str_r1 = rBase[r1].Trim();
    38 
    39                 //区位码第2位
    40                 rnd = new Random(r1 * unchecked((int)DateTime.Now.Ticks) + i);
    41                 int r2;
    42                 if (r1 == 13)
    43                 {
    44                     r2 = rnd.Next(07);
    45                 }
    46                 else
    47                 {
    48                     r2 = rnd.Next(016);
    49                 }
    50                 string str_r2 = rBase[r2].Trim();
    51 
    52                 //区位码第3位
    53                 rnd = new Random(r2 * unchecked((int)DateTime.Now.Ticks) + i);//更换随机种子
    54                 int r3 = rnd.Next(1016);
    55                 string str_r3 = rBase[r3].Trim();
    56 
    57                 //区位码第4位
    58                 rnd = new Random(r3 * unchecked((int)DateTime.Now.Ticks) + i);
    59                 int r4;
    60                 if (r3 == 10)
    61                 {
    62                     r4 = rnd.Next(116);
    63                 }
    64                 else if (r3 == 15)
    65                 {
    66                     r4 = rnd.Next(015);
    67                 }
    68                 else
    69                 {
    70                     r4 = rnd.Next(016);
    71                 }
    72                 string str_r4 = rBase[r4].Trim();
    73 
    74                 //定义两个字节变量存储产生的随机汉字区位码
    75                 byte byte1 = Convert.ToByte(str_r1 + str_r2, 16);
    76                 byte byte2 = Convert.ToByte(str_r3 + str_r4, 16);
    77 
    78                 //将两个字节变量存储在字节数组中
    79                 byte[] str_r = new byte[] { byte1, byte2 };
    80 
    81                 //将产生的一个汉字的字节数组放入object数组中
    82                 bytes.SetValue(str_r, i);
    83             }
    84             return bytes;
    85         }

    4、现在有了素材(随机数),那么再加上图片和困扰就完成了彩色图片验证码--困扰背景+图片Code

     1         /// <summary>
     2         /// 画图片的背景图,干扰
     3         /// </summary>
     4         /// <param name="checkCode"></param>
     5         /// <returns></returns>
     6         private Bitmap CreateImages(string checkCode,string type)
     7         {
     8             int step=0;
     9             if(type=="ch")
    10             {
    11                step=5;//中文字符比较大,所以字距要比较大
    12             }
    13             int iwidth = (int)(checkCode.Length * (13 + step));
    14             System.Drawing.Bitmap image = new System.Drawing.Bitmap(iwidth, 22);
    15             Graphics g = Graphics.FromImage(image);
    16 
    17             g.Clear(Color.White);//清除背景色
    18 
    19             Color[] c = { Color.Black, Color.Red, Color.DarkBlue, Color.Green, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple };//定义随机颜色
    20 
    21             string[] font = { "Verdana""Microsoft Sans Serif""Comic Sans MS""Arial""宋体" };
    22             Random rand = new Random();
    23 
    24             for (int i = 0; i < 50; i++)
    25             {
    26                 int x1 = rand.Next(image.Width);
    27                 int x2 = rand.Next(image.Width);
    28                 int y1 = rand.Next(image.Height);
    29                 int y2 = rand.Next(image.Height);
    30                 g.DrawLine(new Pen(Color.LightGray,1), x1,y1,x2,y2);//根据坐标画线
    31             }
    32 
    33             for (int i = 0; i < checkCode.Length; i++)
    34             {
    35                 int cindex = rand.Next(7);
    36                 int findex = rand.Next(5);
    37 
    38                 Font f = new System.Drawing.Font(font[findex], 10, System.Drawing.FontStyle.Bold);
    39                 Brush b = new System.Drawing.SolidBrush(c[cindex]);
    40                 int ii = 4;
    41                 if ((i + 1% 2 == 0)
    42                 {
    43                     ii = 2;
    44                 }
    45                 g.DrawString(checkCode.Substring(i, 1), f, b, 3 + (i * (12 + stepw)), ii);
    46             }
    47 
    48             g.DrawRectangle(new Pen(Color.Black, 0), 00, image.Width - 1, image.Height - 1);
    49 
    50             System.IO.MemoryStream ms = new System.IO.MemoryStream();
    51             return image;
    52         }

    5、总结

     根据你要的随机数和背景就可以返回BitMap数组,然后把BitMap数组以图片形式存到内存流,就可以返回了。在这里只提供思路与制作方法并没有提供全部代码与封装过程,若对代码有疑问或者需要实例可以加QQ群128584255,大家讨论学习一下。

  • 相关阅读:
    CS 165 notes
    使用GDB和Valgrind调试C程序
    vi编辑器的学习使用(十四)
    vi编辑器的学习使用(十三)
    vi编辑器的学习使用(十)
    vi编辑器的学习使用(十九)
    vi编辑器的学习使用(十八)
    vi编辑器的学习使用(十一)
    vi编辑器的学习使用(十七)
    vi编辑器的学习使用(十五)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/1913510.html
Copyright © 2020-2023  润新知