zoukankan      html  css  js  c++  java
  • 构建一个.net的干货类库,以便于快速的开发

      一个验证码对于一个网站的作用不言而喻,而随着技术的发展验证码的种类也开始多了起来,发展至今很多网站已经不再使用一种验证码,为满足需求程序猿就要写很多的方法来适应需求,今天我就来介绍我之前收集到的验证码的方法写成的一个帮助类,来解决我们日常开发当中的验证码需求问题。

      帮助类中验证码是以byte[]的格式返回的,方便使用。

      英文字符验证码

      

      1  /// <summary>
      2         /// 英文字符验证码
      3         /// </summary>
      4         /// <param name="Code">传出验证码</param>
      5         /// <param name="CodeLength">验证码字符</param>
      6         /// <returns></returns>
      7         public static byte[] GraphCode(out string Code,int CodeLength)
      8         {
      9             int Width = 80;//默认为100
     10             int Height = 30;//默认为40
     11             int FontSize = 20;//默认为20
     12             byte[] bytes = GraphCode(out Code, CodeLength, Width, Height, FontSize);
     13             return bytes;
     14         }
     15 
     16         /// <summary>
     17         /// 产生图形验证码。
     18         /// </summary>
     19         /// <param name="Code">传出验证码。</param>
     20         /// <param name="CodeLength">验证码字符。</param>
     21         /// <param name="Width"></param>
     22         /// <param name="Height"></param>
     23         /// <param name="FontSize"></param>
     24         /// <returns></returns>
     25         public static byte[] GraphCode(out string Code, int CodeLength, int Width, int Height, int FontSize)
     26         {
     27             string code = string.Empty;
     28             String sCode = String.Empty;
     29             //顏色列表,用于验证码、噪线、噪点
     30              Color[] oColors ={
     31              Color.Black,
     32              Color.Red,
     33              Color.Blue,
     34              Color.Green,
     35              Color.Orange,
     36              Color.Brown,
     37              Color.Brown,
     38              Color.DarkBlue
     39             };
     40             //字体列表,用于验证码
     41             string[] oFontNames = { "Times New Roman", "MS Mincho", "Book Antiqua", "Gungsuh", "PMingLiU", "Impact" };
     42             //验证码的字元集
     43             char[] oCharacter = 
     44             {
     45                 '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',
     46                 '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'
     47             };
     48             Random oRnd = new Random();
     49             Bitmap oBmp = null;
     50             Graphics oGraphics = null;
     51             int N1 = 0;
     52             //生成验证码字串
     53             for (N1 = 0; N1 <= CodeLength - 1; N1++)
     54             {
     55                 sCode += oCharacter[oRnd.Next(oCharacter.Length)];
     56             }
     57             oBmp = new Bitmap(Width, Height);
     58             oGraphics = Graphics.FromImage(oBmp);
     59             oGraphics.Clear(Color.White);
     60             try
     61             {
     62                 oGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
     63                 Font f = new System.Drawing.Font("宋体", FontSize, (System.Drawing.FontStyle.Bold));
     64                 // 前景色
     65                 Brush b = new System.Drawing.SolidBrush(Color.Black);
     66                 // 背景色
     67                 oGraphics.Clear(Color.White);
     68                 // 填充文字
     69                 for (int i = 0; i < sCode.Length; i++)
     70                 {
     71                     oGraphics.DrawString(sCode[i].ToString(), f, b, new Rectangle(i * (FontSize - 2), 3, (FontSize - 2), Height));
     72                 }
     73                 // 随机线条
     74                 Pen linePen = new Pen(Color.Gray, 0);
     75                 Random rand = new Random();
     76                 for (int i = 0; i < 3; i++)
     77                 {
     78                     int x1 = rand.Next(oBmp.Width);
     79                     int y1 = rand.Next(oBmp.Height);
     80                     int x2 = rand.Next(oBmp.Width);
     81                     int y2 = rand.Next(oBmp.Height);
     82                     oGraphics.DrawLine(linePen, x1, y1, x2, y2);
     83                 }
     84 
     85                 // 随机点
     86                 for (int i = 0; i < 30; i++)
     87                 {
     88                     int x = rand.Next(oBmp.Width);
     89                     int y = rand.Next(oBmp.Height);
     90                     oBmp.SetPixel(x, y, Color.FromArgb(rand.Next(250), rand.Next(250), rand.Next(250)));
     91                 }
     92 
     93                 Code = sCode;
     94                 //保存图片数据
     95                 MemoryStream stream = new MemoryStream();
     96                 oBmp.Save(stream, ImageFormat.Jpeg);
     97                 //输出图片流
     98                 return stream.ToArray();
     99             }
    100             finally
    101             {
    102                 oGraphics.Dispose();
    103             }
    104         }

    验证码中的字元集是可以改变的,可以去掉一些容易混淆的字元,我这里使用了全部的字元

      数字字符验证码

      1  /// <summary>
      2         /// 纯数字图形验证码
      3         /// </summary>
      4         /// <param name="Code">传出验证码</param>
      5         /// <param name="CodeLength">验证码字符</param>
      6         /// <returns></returns>
      7         public static byte[] NumCode(out string Code, int CodeLength)
      8         {
      9             Code = CreateValidateCode(CodeLength);
     10             byte[] bytes = CreateValidateGraphic(Code);
     11             return bytes;
     12         }
     13         /// <summary>
     14         /// 生成验证码
     15         /// </summary>
     16         /// <param name="CodeLength">指定验证码的长度</param>
     17         /// <returns></returns>
     18         private static string CreateValidateCode(int CodeLength)
     19         {
     20             int[] randMembers = new int[CodeLength];
     21             int[] validateNums = new int[CodeLength];
     22             string validateNumberStr = "";
     23             //生成起始序列值
     24             int seekSeek = unchecked((int)DateTime.Now.Ticks);
     25             Random seekRand = new Random(seekSeek);
     26             int beginSeek = (int)seekRand.Next(0, Int32.MaxValue - CodeLength * 10000);
     27             int[] seeks = new int[CodeLength];
     28             for (int i = 0; i < CodeLength; i++)
     29             {
     30                 beginSeek += 10000;
     31                 seeks[i] = beginSeek;
     32             }
     33             //生成随机数字
     34             for (int i = 0; i < CodeLength; i++)
     35             {
     36                 Random rand = new Random(seeks[i]);
     37                 int pownum = 1 * (int)Math.Pow(10, CodeLength);
     38                 randMembers[i] = rand.Next(pownum, Int32.MaxValue);
     39             }
     40             //抽取随机数字
     41             for (int i = 0; i < CodeLength; i++)
     42             {
     43                 string numStr = randMembers[i].ToString();
     44                 int numCodeLength = numStr.Length;
     45                 Random rand = new Random();
     46                 int numPosition = rand.Next(0, numCodeLength - 1);
     47                 validateNums[i] = Int32.Parse(numStr.Substring(numPosition, 1));
     48             }
     49             //生成验证码
     50             for (int i = 0; i < CodeLength; i++)
     51             {
     52                 validateNumberStr += validateNums[i].ToString();
     53             }
     54             return validateNumberStr;
     55         }
     56 
     57 
     58         /// <summary>
     59         /// 创建验证码的图片
     60         /// </summary>
     61         /// <param name="validateCode">验证码</param>
     62         private static byte[] CreateValidateGraphic(string validateCode)
     63         {
     64             Bitmap image = new Bitmap((int)Math.Ceiling(validateCode.Length * 12.0), 22);
     65             Graphics g = Graphics.FromImage(image);
     66             try
     67             {
     68                 //生成随机生成器
     69                 Random random = new Random();
     70                 //清空图片背景色
     71                 g.Clear(Color.White);
     72                 //画图片的干扰线
     73                 for (int i = 0; i < 25; i++)
     74                 {
     75                     int x1 = random.Next(image.Width);
     76                     int x2 = random.Next(image.Width);
     77                     int y1 = random.Next(image.Height);
     78                     int y2 = random.Next(image.Height);
     79                     g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
     80                 }
     81                 Font font = new Font("Arial", 12, (FontStyle.Bold | FontStyle.Italic));
     82                 LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height),
     83                  Color.Blue, Color.DarkRed, 1.2f, true);
     84                 g.DrawString(validateCode, font, brush, 3, 2);
     85                 //画图片的前景干扰点
     86                 for (int i = 0; i < 100; i++)
     87                 {
     88                     int x = random.Next(image.Width);
     89                     int y = random.Next(image.Height);
     90                     image.SetPixel(x, y, Color.FromArgb(random.Next()));
     91                 }
     92                 //画图片的边框线
     93                 g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
     94                 //保存图片数据
     95                 MemoryStream stream = new MemoryStream();
     96                 image.Save(stream, ImageFormat.Jpeg);
     97                 //输出图片流
     98                 return stream.ToArray();
     99             }
    100             finally
    101             {
    102                 g.Dispose();
    103                 image.Dispose();
    104             }
    105         }

    数字与字符混合验证码

      1  /// <summary>
      2         /// 生成随机字符串
      3         /// </summary>
      4         /// <param name="NumCount"></param>
      5         /// <returns></returns>
      6         private static string CreateRandomNum(int NumCount)
      7         {
      8             char[] allCharArray = 
      9             {
     10                 '1','2','3','4','5','6','7','8','9',
     11                 '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',
     12                 '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'                                    
     13             };
     14             string randomNum = "";
     15             int temp = -1;//记录上次随机数的数值,尽量避免产生几个相同的随机数 
     16             Random rand = new Random();
     17             for (int i = 0; i < NumCount; i++)
     18             {
     19                 if (temp != -1)
     20                 {
     21                     rand = new Random(i * temp * ((int)DateTime.Now.Ticks));
     22                 }
     23                 int t = rand.Next(35);
     24                 if (temp == t)
     25                 {
     26                     return CreateRandomNum(NumCount);
     27                 }
     28                 temp = t;
     29                 randomNum += allCharArray[t];
     30             }
     31             return randomNum;
     32         }
     33 
     34         /// <summary>
     35         /// 数字和字符混合验证码
     36         /// </summary>
     37         /// <param name="Code">传出字符</param>
     38         /// <param name="NumCount">字节长度</param>
     39         /// <param name="Width">图片宽度</param>
     40         /// <param name="Height">图片长度</param>
     41         /// <param name="FontSize">文字大小</param>
     42         /// <returns></returns>
     43         public static byte[] GNCode(out string Code, int NumCount, int Width, int Height, int FontSize)
     44         {
     45             string validateNum = CreateRandomNum(NumCount);
     46             Code = null;
     47             if (validateNum == null || validateNum.Trim() == String.Empty)
     48                 return null;
     49             //生成Bitmap图像 
     50             System.Drawing.Bitmap image = new System.Drawing.Bitmap(Width, Height);
     51             Graphics g = Graphics.FromImage(image);
     52 
     53             try
     54             {
     55                 //生成随机生成器 
     56                 Random random = new Random();
     57 
     58                 //清空图片背景色 
     59                 g.Clear(Color.White);
     60 
     61                 g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
     62                 Font f = new System.Drawing.Font("宋体", FontSize, (System.Drawing.FontStyle.Bold));
     63                 // 前景色
     64                 Brush b = new System.Drawing.SolidBrush(Color.Black);
     65                 // 背景色
     66                 g.Clear(Color.White);
     67                 // 填充文字
     68                 for (int i = 0; i < validateNum.Length; i++)
     69                 {
     70                     g.DrawString(validateNum[i].ToString(), f, b, new Rectangle(i * (FontSize - 2), 3, (FontSize - 2), Height));
     71                 }
     72                 // 随机线条
     73                 Pen linePen = new Pen(Color.Gray, 0);
     74                 Random rand = new Random();
     75                 for (int i = 0; i < 3; i++)
     76                 {
     77                     int x1 = rand.Next(image.Width);
     78                     int y1 = rand.Next(image.Height);
     79                     int x2 = rand.Next(image.Width);
     80                     int y2 = rand.Next(image.Height);
     81                     g.DrawLine(linePen, x1, y1, x2, y2);
     82                 }
     83 
     84                 // 随机点
     85                 for (int i = 0; i < 30; i++)
     86                 {
     87                     int x = rand.Next(image.Width);
     88                     int y = rand.Next(image.Height);
     89                     image.SetPixel(x, y, Color.FromArgb(rand.Next(250), rand.Next(250), rand.Next(250)));
     90                 }
     91 
     92                 Code = validateNum;
     93 
     94                 //保存图片数据
     95                 MemoryStream stream = new MemoryStream();
     96                 image.Save(stream, ImageFormat.Jpeg);
     97                 //输出图片流
     98                 return stream.ToArray();
     99             }
    100             finally
    101             {
    102                 g.Dispose();
    103                 image.Dispose();
    104             }
    105         }

    数学算式验证码

     1 /// <summary>
     2         /// 数学算式的验证码
     3         /// </summary>
     4         /// <param name="Code"></param>
     5         /// <returns></returns>
     6         public static byte[] MathVerifyCode(out int Code)
     7         {
     8             int mathResult = 0;
     9             string expression = null;
    10 
    11             Random rnd = new Random();
    12 
    13             ////生成3个10以内的整数,用来运算
    14             int operator1 = rnd.Next(0, 10);
    15             int operator2 = rnd.Next(10, 100);
    16             int operator3 = rnd.Next(0, 10);
    17 
    18             ////随机组合运算顺序,只做 + 和 - 运算
    19             switch (rnd.Next(0, 3))
    20             {
    21                 case 0:
    22                     mathResult = operator1 + operator2 + operator3;
    23                     expression = string.Format("{0} + {1} + {2} = ?", operator1, operator2, operator3);
    24                     break;
    25                 case 1:
    26                     mathResult = operator2 - operator1 + operator3;
    27                     expression = string.Format("{0} - {1} + {2} = ?", operator2, operator1, operator3);
    28                     break;
    29                 default:
    30                     mathResult = operator2 + operator1 - operator3;
    31                     expression = string.Format("{0} + {1} - {2} = ?", operator2, operator1, operator3);
    32                     break;
    33             }
    34             Code = mathResult;
    35             using (Bitmap bmp = new Bitmap(150, 25))
    36             {
    37                 using (Graphics graph = Graphics.FromImage(bmp))
    38                 {
    39                     graph.Clear(Color.FromArgb(232, 238, 247)); ////背景色,可自行设置
    40 
    41                     ////画噪点
    42                     for (int i = 0; i <= 128; i++)
    43                     {
    44                         graph.DrawRectangle(
    45                             new Pen(Color.FromArgb(rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255))),
    46                             rnd.Next(2, 128),
    47                             rnd.Next(2, 38),
    48                             1,
    49                             1);
    50                     }
    51 
    52                     ////输出表达式
    53                     for (int i = 0; i < expression.Length; i++)
    54                     {
    55                         graph.DrawString(expression.Substring(i, 1),
    56                             new Font(FontFamily.GenericSansSerif, 12, FontStyle.Bold),
    57                             new SolidBrush(Color.FromArgb(rnd.Next(255), rnd.Next(128), rnd.Next(255))),
    58                             5 + i * 10,
    59                             rnd.Next(1, 5));
    60                     }
    61 
    62                     ////画边框,不需要可以注释掉
    63                     graph.DrawRectangle(new Pen(Color.Firebrick), 0, 0, 150 - 1, 25 - 1);
    64                 }
    65 
    66                 MemoryStream stream = new MemoryStream();
    67                 bmp.Save(stream, ImageFormat.Jpeg);
    68                 //输出图片流
    69                 return stream.ToArray();
    70             }
    71         }

    数学算式验证码里面的算式结构是可以改成更复杂的,不过个人觉得加减法已经可以满足日常需求

    使用方式

    以ASP.NET MVC为例,使用方式很简单,写一个方法,以图片文件的形式输出

     1         /// <summary>
     2         /// 验证码
     3         /// </summary>
     4         /// <returns></returns>
     5         public virtual ActionResult VerifyImage()
     6         {
     7             string Code = "";
     8             byte[] bytes = CodeHelper.GNCode(out Code, 4, 80, 26, 20);
     9             Session["Code"] = Code;
    10             return File(bytes, @"image/jpeg");
    11         }

    这里的CodeHelper就是我们写好的验证码帮助类,直接调用

    前端放一张图片来显示验证码

    <img  src="@Url.Action("VerifyImage")" id="VerifyImage" title="点击换一个">

    应用截图

  • 相关阅读:
    Teamwork[HDU4494]
    The Parallel Challenge Ballgame[HDU1101]
    「JSOI2016」无界单词
    「SCOI2015」小凸玩密室
    #3636. IIIDX(iiidx)
    #2652. 背单词(word)
    「JXOI2017」加法
    拙者
    19.10.01 acm E:Lowest Common Ancestor
    #3391. big
  • 原文地址:https://www.cnblogs.com/starmile/p/5735974.html
Copyright © 2011-2022 走看看