.NET 验证码/验证图片

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

 

posted on 2015-07-08 14:49  勤劳的Coder  阅读(320)  评论(0)    收藏  举报