构建一个.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="点击换一个">

 

应用截图

 

posted @ 2016-08-04 11:19  starmile  阅读(708)  评论(3编辑  收藏  举报