代码改变世界

Asp.net波形随机验证码

2010-08-11 13:27  空逸云  阅读(513)  评论(4编辑  收藏  举报

       网上有许多关于验证码生成的类.鉴于以后方便.自写了一个波形验证码,其中波形操作参考了.无刷新仿google波形扭曲彩色Asp.net验证码.  代码如下

代码
  1 
  2  /// <summary>
  3     /// 验证码操作类
  4     /// </summary>
  5     public class VerifyCode
  6     {
  7         private string _generateCode = string.Empty;
  8         private const double PI2 = 6.283185307179586476925286766559;
  9 
 10         /// <summary>
 11         ///绘制的符号数量
 12         /// </summary>
 13         /// <value>The code count.</value>
 14         public int CodeCount { getset; }
 15 
 16         /// <summary>
 17         /// 生成的验证码
 18         /// </summary>
 19         /// <value>The generate code.</value>
 20         public string GenerateCode { get { return _generateCode; } }
 21 
 22         /// <summary>
 23         /// 验证码字体
 24         /// </summary>
 25         /// <value>The font family.</value>
 26         public FontFamily FontFamily { getset; }
 27 
 28         /// <summary>
 29         /// 字体大小
 30         /// </summary>
 31         /// <value>The size of the font.</value>
 32         public int FontSize { getset; }
 33 
 34         /// <summary>
 35         ///是否扭曲
 36         /// </summary>
 37         /// <value><c>true</c> if wave; otherwise, <c>false</c>.</value>
 38         public bool Wave { getset; }
 39 
 40         /// <summary>
 41         /// 扭曲方向,true为纵向,false为横向
 42         /// </summary>
 43         /// <value><c>true</c> if [wave dir]; otherwise, <c>false</c>.</value>
 44         public bool WaveDirc { getset; }
 45 
 46         /// <summary>
 47         /// 波形扭曲幅度
 48         /// </summary>
 49         /// <value>The wave value.</value>
 50         public int WaveValue { getset; }
 51 
 52         /// <summary>
 53         /// 波形起始相位
 54         /// </summary>
 55         /// <value>The wave phase.</value>
 56         public double WavePhase { getset; }
 57 
 58         public VerifyCode(int codeCount)
 59         {
 60             CodeCount = codeCount;
 61             FontFamily = new FontFamily("Arial");
 62             FontSize = 40;
 63             Wave = true;
 64             WaveDirc = false;
 65             WaveValue = 12;
 66             WavePhase = 10;
 67         }
 68 
 69         /// <summary>
 70         /// 创建图片并输出
 71         /// </summary>
 72         /// <param name="context">The context.</param>
 73         public void CreateImage(HttpContext context)
 74         {
 75             CreateCheckCodeImage(CreateRandomCode(CodeCount), context);
 76         }
 77 
 78         /// <summary>
 79         /// 生成随机数
 80         /// </summary>
 81         /// <param name="codeCount">The code count.</param>
 82         /// <returns></returns>
 83         private string CreateRandomCode(int codeCount)
 84         {
 85             int number;
 86 
 87             Random random = new Random();
 88 
 89             for (int i = 0; i < codeCount; i++)
 90             {
 91                 //随机整数
 92                 number = random.Next();
 93 
 94                 //字符从0-9,A-Z中随机产生,对应的ASCII码为 48-57,65-90
 95                 number = number % 36;
 96 
 97                 if (number < 10)
 98                 {
 99                     number += 48;
100                 }
101                 else
102                 {
103                     number += 55;
104                 }
105                 _generateCode += ((char)number).ToString();
106             }
107             return _generateCode;
108         }
109 
110         /// <summary>
111         /// 生成验证码图片
112         /// </summary>
113         /// <param name="checkCode">The check code.</param>
114         /// <param name="context">The context.</param>
115         private void CreateCheckCodeImage(string checkCode, HttpContext context)
116         {
117             //若验证码为空,直接返回
118             if (string.IsNullOrEmpty(checkCode))
119                 return;
120             //根据验证码的长度确定输出图片的长度
121             Bitmap image = new Bitmap((int)Math.Ceiling((checkCode.Length * (FontSize + 4.5))), FontSize * 2);
122             //创建Graphs对象
123             Graphics g = Graphics.FromImage(image);
124 
125             try
126             {
127                 Random random = new Random();
128                 //清空图片背景色
129                 g.Clear(Color.White);
130                 //画图片的背景噪音线25条
131                 for (int i = 0; i < 25; i++)
132                 {
133                     //噪音线的坐标(x1,y1),(x2,y2)
134                     int x1 = random.Next(image.Width);
135                     int x2 = random.Next(image.Width);
136                     int y1 = random.Next(image.Height);
137                     int y2 = random.Next(image.Height);
138                     //用银色画出噪音线
139                     g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
140                 }
141                 //输出图片中的验证码
142                 Font font = new Font(FontFamily, FontSize, (FontStyle.Bold | FontStyle.Italic));
143                 //线性渐变笔刷
144                 LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(00, image.Width, image.Height), Color.Green, RandomColor(), 1.2ftrue);
145                 g.DrawString(checkCode, font, brush, 00);
146 
147                 //图片的前景噪音点 
148                 for (int i = 0; i < 50; i++)
149                 {
150                     int x = random.Next(image.Width);
151                     int y = random.Next(image.Height);
152                     image.SetPixel(x, y, Color.FromArgb(random.Next()));
153                 }
154                 //画图片的边框线
155                 g.DrawRectangle(new Pen(Color.Peru), 00, image.Width - 1, image.Height - 1);
156 
157                 if (Wave)//是否扭曲
158                     image = TwistImage(image, WaveDirc, WaveValue, WavePhase);
159 
160                 //创建内存刘用于输出图片
161                 using (MemoryStream ms = new MemoryStream())
162                 {
163                     //图片格式指定为JPG
164                     image.Save(ms, ImageFormat.Jpeg);
165                     //清空缓冲区流中的所有输出
166                     context.Response.ClearContent();
167                     //输出流的HTTP MIME类型设置
168                     context.Response.ContentType = "image/Jpeg";
169                     //输出图片的二进制流
170                     context.Response.BinaryWrite(ms.ToArray());
171                 }
172             }
173             finally
174             {
175                 g.Dispose();
176                 image.Dispose();
177             }
178         }
179 
180         /// <summary>
181         /// 正弦曲线Wave扭曲图片
182         /// </summary>
183         /// <param name="srcBmp">源图片.</param>
184         /// <param name="bxDir">扭曲方向</param>
185         /// <param name="dMultValue">波形的幅度倍数,越大扭曲的程度越高,一般为3</param>
186         /// <param name="dPhase">波形的起始相位,取值区间[0-2*PI]</param>
187         /// <returns></returns>
188         private Bitmap TwistImage(Bitmap srcBmp, bool bxDir, double dMultValue, double dPhase)
189         {
190             Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
191 
192             //将位图背景填充为白色
193             Graphics graph = Graphics.FromImage(destBmp);
194             graph.FillRectangle(new SolidBrush(Color.White), 00, destBmp.Width, destBmp.Height);
195             graph.Dispose();
196 
197             double dBaseAxisLen = bxDir ? (double)destBmp.Height : (double)destBmp.Width;
198 
199             for (int i = 0; i < destBmp.Width; i++)
200             {
201                 for (int j = 0; j < destBmp.Height; j++)
202                 {
203                     double dx = 0;
204                     dx = bxDir ? (PI2 * (double)j) / dBaseAxisLen : (PI2 * (double)i) / dBaseAxisLen;
205                     dx += dPhase;
206                     double dy = Math.Sin(dx);
207 
208                     //取得当前点的颜色
209                     int nOldX = 0, nOldY = 0;
210                     nOldX = bxDir ? i + (int)(dy * dMultValue) : i;
211                     nOldY = bxDir ? j : j + (int)(dy * dMultValue);
212 
213                     Color color = srcBmp.GetPixel(i, j);
214                     if (nOldX >= 0 && nOldX < destBmp.Width && nOldY >= 0 && nOldY < destBmp.Height)
215                     {
216                         destBmp.SetPixel(nOldX, nOldY, color);
217                     }
218                 }
219             }
220             return destBmp;
221         }
222 
223         /// <summary>
224         /// 随机颜色
225         /// </summary>
226         /// <returns></returns>
227         private Color RandomColor()
228         {
229             Random randomNumFirst = new Random(DateTime.Now.Millisecond);
230             Random randomNumSencond = new Random(DateTime.Now.Millisecond);
231 
232             int red = randomNumFirst.Next(256);
233             int green = randomNumSencond.Next(256);
234             int blue = (red + green > 400? 0 : 400 - red - green;
235             blue = blue > 255 ? 255 : blue;
236             return Color.FromArgb(red, green, blue);
237         }
238     }

 

 使用时.可以直接添加一个IHttpHandler子类.

 


VerifyCode code 
= new VerifyCode(5);
code.CreateImage(context);
context.Session.Add(
"VerifyCode", code.GenerateCode);

 

 此外.VerifyCode类还提供了其他的属性.可在初始化时利用3.0的特性初始化,也可以在初始化后进行赋值.

最后在WebConfig配置相关Handler配置.成果如下