验证码帮助类

  1 using System;
  2 using System.Web;
  3 using System.Drawing;
  4 using System.Security.Cryptography;
  5 
  6 namespace DotNet.Utilities
  7 {
  8     /// <summary>
  9     /// 验证码类
 10     /// </summary>
 11     public class Rand
 12     {
 13         #region 生成随机数字
 14         /// <summary>
 15         /// 生成随机数字
 16         /// </summary>
 17         /// <param name="length">生成长度</param>
 18         public static string Number(int Length)
 19         {
 20             return Number(Length, false);
 21         }
 22 
 23         /// <summary>
 24         /// 生成随机数字
 25         /// </summary>
 26         /// <param name="Length">生成长度</param>
 27         /// <param name="Sleep">是否要在生成前将当前线程阻止以避免重复</param>
 28         public static string Number(int Length, bool Sleep)
 29         {
 30             if (Sleep) System.Threading.Thread.Sleep(3);
 31             string result = "";
 32             System.Random random = new Random();
 33             for (int i = 0; i < Length; i++)
 34             {
 35                 result += random.Next(10).ToString();
 36             }
 37             return result;
 38         }
 39         #endregion
 40 
 41         #region 生成随机字母与数字
 42         /// <summary>
 43         /// 生成随机字母与数字
 44         /// </summary>
 45         /// <param name="IntStr">生成长度</param>
 46         public static string Str(int Length)
 47         {
 48             return Str(Length, false);
 49         }
 50 
 51         /// <summary>
 52         /// 生成随机字母与数字
 53         /// </summary>
 54         /// <param name="Length">生成长度</param>
 55         /// <param name="Sleep">是否要在生成前将当前线程阻止以避免重复</param>
 56         public static string Str(int Length, bool Sleep)
 57         {
 58             if (Sleep) System.Threading.Thread.Sleep(3);
 59             char[] Pattern = new char[] { '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', 'V', 'W', 'X', 'Y', 'Z' };
 60             string result = "";
 61             int n = Pattern.Length;
 62             System.Random random = new Random(~unchecked((int)DateTime.Now.Ticks));
 63             for (int i = 0; i < Length; i++)
 64             {
 65                 int rnd = random.Next(0, n);
 66                 result += Pattern[rnd];
 67             }
 68             return result;
 69         }
 70         #endregion
 71 
 72         #region 生成随机纯字母随机数
 73         /// <summary>
 74         /// 生成随机纯字母随机数
 75         /// </summary>
 76         /// <param name="IntStr">生成长度</param>
 77         public static string Str_char(int Length)
 78         {
 79             return Str_char(Length, false);
 80         }
 81 
 82         /// <summary>
 83         /// 生成随机纯字母随机数
 84         /// </summary>
 85         /// <param name="Length">生成长度</param>
 86         /// <param name="Sleep">是否要在生成前将当前线程阻止以避免重复</param>
 87         public static string Str_char(int Length, bool Sleep)
 88         {
 89             if (Sleep) System.Threading.Thread.Sleep(3);
 90             char[] Pattern = new char[] { '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' };
 91             string result = "";
 92             int n = Pattern.Length;
 93             System.Random random = new Random(~unchecked((int)DateTime.Now.Ticks));
 94             for (int i = 0; i < Length; i++)
 95             {
 96                 int rnd = random.Next(0, n);
 97                 result += Pattern[rnd];
 98             }
 99             return result;
100         }
101         #endregion
102     }
103 
104     /// <summary>
105     /// 验证图片类
106     /// </summary>
107     public class YZMHelper
108     {
109         #region 私有字段
110         private string text;
111         private Bitmap image;
112         private int letterCount = 4;   //验证码位数
113         private int letterWidth = 16;  //单个字体的宽度范围
114         private int letterHeight = 20; //单个字体的高度范围
115         private static byte[] randb = new byte[4];
116         private static RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider();
117         private Font[] fonts = 
118     {
119        new Font(new FontFamily("Times New Roman"),10 +Next(1),System.Drawing.FontStyle.Regular),
120        new Font(new FontFamily("Georgia"), 10 + Next(1),System.Drawing.FontStyle.Regular),
121        new Font(new FontFamily("Arial"), 10 + Next(1),System.Drawing.FontStyle.Regular),
122        new Font(new FontFamily("Comic Sans MS"), 10 + Next(1),System.Drawing.FontStyle.Regular)
123     };
124         #endregion
125 
126         #region 公有属性
127         /// <summary>
128         /// 验证码
129         /// </summary>
130         public string Text
131         {
132             get { return this.text; }
133         }
134 
135         /// <summary>
136         /// 验证码图片
137         /// </summary>
138         public Bitmap Image
139         {
140             get { return this.image; }
141         }
142         #endregion
143 
144         #region 构造函数
145         public YZMHelper()
146         {
147             HttpContext.Current.Response.Expires = 0;
148             HttpContext.Current.Response.Buffer = true;
149             HttpContext.Current.Response.ExpiresAbsolute = DateTime.Now.AddSeconds(-1);
150             HttpContext.Current.Response.AddHeader("pragma", "no-cache");
151             HttpContext.Current.Response.CacheControl = "no-cache";
152             this.text = Rand.Number(4);
153             CreateImage();
154         }
155         #endregion
156 
157         #region 私有方法
158         /// <summary>
159         /// 获得下一个随机数
160         /// </summary>
161         /// <param name="max">最大值</param>
162         private static int Next(int max)
163         {
164             rand.GetBytes(randb);
165             int value = BitConverter.ToInt32(randb, 0);
166             value = value % (max + 1);
167             if (value < 0) value = -value;
168             return value;
169         }
170 
171         /// <summary>
172         /// 获得下一个随机数
173         /// </summary>
174         /// <param name="min">最小值</param>
175         /// <param name="max">最大值</param>
176         private static int Next(int min, int max)
177         {
178             int value = Next(max - min) + min;
179             return value;
180         }
181         #endregion
182 
183         #region 公共方法
184         /// <summary>
185         /// 绘制验证码
186         /// </summary>
187         public void CreateImage()
188         {
189             int int_ImageWidth = this.text.Length * letterWidth;
190             Bitmap image = new Bitmap(int_ImageWidth, letterHeight);
191             Graphics g = Graphics.FromImage(image);
192             g.Clear(Color.White);
193             for (int i = 0; i < 2; i++)
194             {
195                 int x1 = Next(image.Width - 1);
196                 int x2 = Next(image.Width - 1);
197                 int y1 = Next(image.Height - 1);
198                 int y2 = Next(image.Height - 1);
199                 g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
200             }
201             int _x = -12, _y = 0;
202             for (int int_index = 0; int_index < this.text.Length; int_index++)
203             {
204                 _x += Next(12, 16);
205                 _y = Next(-2, 2);
206                 string str_char = this.text.Substring(int_index, 1);
207                 str_char = Next(1) == 1 ? str_char.ToLower() : str_char.ToUpper();
208                 Brush newBrush = new SolidBrush(GetRandomColor());
209                 Point thePos = new Point(_x, _y);
210                 g.DrawString(str_char, fonts[Next(fonts.Length - 1)], newBrush, thePos);
211             }
212             for (int i = 0; i < 10; i++)
213             {
214                 int x = Next(image.Width - 1);
215                 int y = Next(image.Height - 1);
216                 image.SetPixel(x, y, Color.FromArgb(Next(0, 255), Next(0, 255), Next(0, 255)));
217             }
218             image = TwistImage(image, true, Next(1, 3), Next(4, 6));
219             g.DrawRectangle(new Pen(Color.LightGray, 1), 0, 0, int_ImageWidth - 1, (letterHeight - 1));
220             this.image = image;
221         }
222 
223         /// <summary>
224         /// 字体随机颜色
225         /// </summary>
226         public Color GetRandomColor()
227         {
228             Random RandomNum_First = new Random((int)DateTime.Now.Ticks);
229             System.Threading.Thread.Sleep(RandomNum_First.Next(50));
230             Random RandomNum_Sencond = new Random((int)DateTime.Now.Ticks);
231             int int_Red = RandomNum_First.Next(180);
232             int int_Green = RandomNum_Sencond.Next(180);
233             int int_Blue = (int_Red + int_Green > 300) ? 0 : 400 - int_Red - int_Green;
234             int_Blue = (int_Blue > 255) ? 255 : int_Blue;
235             return Color.FromArgb(int_Red, int_Green, int_Blue);
236         }
237 
238         /// <summary>
239         /// 正弦曲线Wave扭曲图片
240         /// </summary>
241         /// <param name="srcBmp">图片路径</param>
242         /// <param name="bXDir">如果扭曲则选择为True</param>
243         /// <param name="nMultValue">波形的幅度倍数,越大扭曲的程度越高,一般为3</param>
244         /// <param name="dPhase">波形的起始相位,取值区间[0-2*PI)</param>
245         public System.Drawing.Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase)
246         {
247             double PI = 6.283185307179586476925286766559;
248             Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
249             Graphics graph = Graphics.FromImage(destBmp);
250             graph.FillRectangle(new SolidBrush(Color.White), 0, 0, destBmp.Width, destBmp.Height);
251             graph.Dispose();
252             double dBaseAxisLen = bXDir ? (double)destBmp.Height : (double)destBmp.Width;
253             for (int i = 0; i < destBmp.Width; i++)
254             {
255                 for (int j = 0; j < destBmp.Height; j++)
256                 {
257                     double dx = 0;
258                     dx = bXDir ? (PI * (double)j) / dBaseAxisLen : (PI * (double)i) / dBaseAxisLen;
259                     dx += dPhase;
260                     double dy = Math.Sin(dx);
261                     int nOldX = 0, nOldY = 0;
262                     nOldX = bXDir ? i + (int)(dy * dMultValue) : i;
263                     nOldY = bXDir ? j : j + (int)(dy * dMultValue);
264 
265                     Color color = srcBmp.GetPixel(i, j);
266                     if (nOldX >= 0 && nOldX < destBmp.Width
267                      && nOldY >= 0 && nOldY < destBmp.Height)
268                     {
269                         destBmp.SetPixel(nOldX, nOldY, color);
270                     }
271                 }
272             }
273             srcBmp.Dispose();
274             return destBmp;
275         }
276         #endregion
277     }
278 }
原文地址:https://www.cnblogs.com/itliuyang/p/6640158.html