哈哈,今天来一篇关于验证码的随笔吧。感觉验证码在周围无处不在,就像美女变幻莫测,捉摸不定。不过说实话我超级的厌恶那个东东,着实不爽,一个降低用户体验的邪恶东西,可是似乎每个网站的登录和注册(特别是注册)都要加这个让人厌恶的东西,目的很简单,就是防止有一些大神级的人物暴力登录亦或者恶意注册,存在必有其价值吧!废话少说,进入正题,现在的验证码已经有很多了,简单的随机生成图片、寻找图片的指定颜色字符,简单算术计算以及语音播放等等,今天要写的使用的最多的第一种混合数字字符的图片。
相信大家对Random这个已经蛮熟悉了吧,随机生成就要用到,贴出随机生成验证码代码
1 /// <summary> 2 /// 动态生成指定数目的随机数或字母 3 /// </summary> 4 /// <param name="num">整数</param> 5 /// <returns>返回验证码字符串</returns> 6 private string GenerateCheckCode(int num) 7 { 8 int number; //定义变量 9 char code; 10 string checkCode = String.Empty; //空字符串,只读 11 Random random = new Random(); //定义随机变量实例 12 for (int i=0; i < num;i++ ) 13 { 14 //利用for循环生成指定数目的随机数或字母 15 number = random.Next(); //返回一个小于指定的最大值的非负的随机数 next有三个构造函数 16 if (number % 2 == 0) 17 { 18 //产生一个一位数 19 code = (char)('0' + (char)(number % 10)); 20 } 21 else 22 { 23 //产生一个字母 24 code = (char)('C'+(char)(number % 26)); 25 } 26 checkCode += code.ToString(); 27 } 28 return checkCode; 29 }
好了,当然我这里生成的是四位的验证码,你也可以更改参数来更改,接下来就是重点的重点啦,我们都知道现在有破解验证码的工具,一般的就是将你生成的验证码图片按字符个数切割,然后
根据图片的位点和字符,数字,特殊符号对比匹配,达到破解的目的(不知道说的对不对啦,不对的话请大神指正)
接下来将生成的验证码字符串生成图片,代码如下:
1 /// <summary> 2 /// 根据验证码字符串生成验证码图片 3 /// </summary> 4 /// <param name="checkCode">验证码字符串</param> 5 private void CreateCheckCodeImage(string checkCode) 6 { 7 8 if (checkCode == null || checkCode.Trim() == String.Empty) return; 9 // 引用System.Drawing类库 10 Bitmap myImage = new Bitmap(60, 30);//生成一个指定大小的位图 11 Graphics graphics = Graphics.FromImage(myImage); //从一个位图生成一个画布 12 try 13 { 14 graphics.Clear(Color.White); //清除整个绘画面并以指定的背景色填充,这里是把背景色设为白色 15 Random random = new Random(); //实例化一个伪随机数生成器 16 17 //画图片的前景噪音点,这里有200个 18 for (int i = 0; i < 200; i++) 19 { 20 int x = random.Next(myImage.Width); 21 int y = random.Next(myImage.Height); 22 myImage.SetPixel(x, y, Color.FromArgb(random.Next()));//指定坐标为x,y处的像素的颜色 23 } 24 25 //画图片的背景噪音线,这里为5条 26 for (int i = 0; i < 5; i++) 27 { 28 int x1 = random.Next(myImage.Width); 29 int x2 = random.Next(myImage.Width); 30 int y1 = random.Next(myImage.Height); 31 int y2 = random.Next(myImage.Height); 32 //绘制一条坐标x1,y1到坐标x2,y2的指定颜色的线条,这里的线条为黑色 33 graphics.DrawLine(new Pen(Color.Black), x1, y1, x2, y2); 34 } 35 //定义特定的文本格式,这里的字体为Arial,大小为15,字体加粗 36 Font font = new Font("Arial", 15, FontStyle.Italic); 37 //根据矩形、起始颜色和结束颜色以及方向角度产生一个LinearGradientBrush实例---线性渐变 38 System.Drawing.Drawing2D.LinearGradientBrush brush = 39 new System.Drawing.Drawing2D.LinearGradientBrush( 40 new Rectangle(0, 0, myImage.Width, myImage.Height),//在坐标0,0处实例化一个和myImage同样大小的矩形 41 Color.Blue, Color.Red, 1.2f, true); 42 //绘制文本字符串 43 graphics.DrawString(checkCode, font, brush, 2, 2); 44 45 //绘制有坐标对、宽度和高度指定的矩形---画图片的边框线 46 graphics.DrawRectangle(new Pen(Color.Silver), 0, 0, myImage.Width - 1, myImage.Height - 1); 47 //创建其支持存储器为内存的流 48 MemoryStream ms = new MemoryStream(); 49 //将此图像以指定格式保存到指定的流中 50 myImage.Save(ms, System.Drawing.Imaging.ImageFormat.Gif); //这里是以gif的格式保存到内存中 51 HttpContext.Current.Response.ClearContent(); //清除缓冲区流中的所有内容输出 52 HttpContext.Current.Response.ContentType = "image/Gif"; //获取或设置输出流的HTTP MIME类型 53 HttpContext.Current.Response.BinaryWrite(ms.ToArray()); //将一个二进制字符串写入HTTP输出流 54 } 55 finally 56 { 57 //释放占用资源 58 graphics.Dispose(); 59 myImage.Dispose(); 60 } 61 }
好了,然后添加一个一般处理程序(后缀名为.ashx)《添加新项->一般处理程序》-----------我这里就命名为SecurityCode.ashx
1 /// <summary> 2 /// 验证码 的摘要说明 3 /// </summary> 4 public class SecurityCode : IHttpHandler 5 { 6 7 public void ProcessRequest(HttpContext context) 8 { 9 DrawingSecurityCode sc = new DrawingSecurityCode(); 10 string SecurityCode = sc.GetSecurityCode(4); 11 } 12 13 public bool IsReusable 14 { 15 get 16 { 17 return false; 18 } 19 } 20 }
到此为止,后台代码完成,接下来就是简单的前台代码了
1 <img id="CodeImg" src="SecurityCode.ashx" alt="验证码" onclick="javascript:RefreshCode();" /> 2 3 <script type="text/javascript"> 4 function RefreshCode() { 5 var random = Math.random(); 6 var img = document.getElementById("CodeImg"); 7 img.src = "SecurityCode.ashx?" + random; 8 } 9 </script>
好了,基本完成了,贴一张图片吧