• 详细说说如何生成验证码—ASP.NET细枝末节(4)


    前言

    今天小编详细的说一下,ASP.NET网站开发过程中生成验证码的全部问题。

    本文的目标,是让读者了解,生成验证码涉及的全部基础知识问题。

    当然这里说的是比较简单的验证码。

    真正符合要求的验证码,涉及到计算机图形学的一些问题,这就不是网站开发人员该考虑的了,公司肯定有专人干这个,或者有开发包。

    1.为啥要研究这东西?

    在正文开始之前,我又几个问题要强调。

    1.对于验证码的生成问题,即使完全不了解,也不会影响开发。

    我们完全可以到网上C+V一点代码搞定(也就是说,这不是asp.net网站开发的核心问题)。

    坦率的讲,对于今天写的东西,小编不翻资料也是记不住。

    2.但是,小编有个习惯。就是如果一段代码我完全不理解的话。

    那么即使我知道他粘贴下来就能用,我心里也不是很踏实。

    所以,可以写不出来,但一定要略懂,  心里踏实。

    2.学习流程

    本文的学习流程是这样安排的。

    clipboard

    那么我们开始

    一个简单的GDI小案例

    1.说明

    如果你想思考如何生成验证码,那么您第一个要解决的问题,

    一定是.NET动态生成图片问题。(知道的就算了)

    //GDI:.Net程序中进行绘图的一些类。

    2.代码

     

     1             //这段代码开始前,要添加System.Drawing的引用。
     2             //创建一个尺寸为500*500的内存图片
     3             using (Bitmap bmp = new Bitmap(500, 500))
     4             //得到图片的画布 
     5             using (Graphics g = Graphics.FromImage(bmp))
     6             {
     7                 //创建画笔
     8                 using (Font font = new Font(FontFamily.GenericSerif, 30))
     9                  {
    10                       //在100,100处画一个红色的helloWorld
    11                       g.DrawString("HelloWorld", font, Brushes.Red, 100, 100);
    12                       //在100,100处画一个蓝色的椭圆
    13                       g.DrawEllipse(Pens.Blue, 100, 100, 100, 100);
    14  
    15                       using (Stream stream = File.OpenWrite(@"d:2.jpg"))
    16                       {
    17                             bmp.Save(stream, ImageFormat.Jpeg);
    18                        }
    19                  }
    20             } 

    看这就生成完了。代码上,貌似没什么需要解释的。

    clipboard[1]

     

    用一般处理程序返回一个图片

    1.说明

    接下来我们研究一下如何在网页中动态生成一个图片。

    从代码的角度上看。跟上边控制台上的代码仅有几点简单区别,几乎一样!

    1)一般处理程序需要先设置ContentType =“image/jpeg”

    2)一般处理程序需要把图片保存到Response.OutputStream中

    2.代码

     1             context.Response.ContentType = "image/jpeg";
     2 
     3             //这段代码开始前,要添加System.Drawing的引用。
     4             //创建一个尺寸为500*500的内存图片
     5             using (Bitmap bmp = new Bitmap(500, 500))
     6             //得到图片的画布 
     7             using (Graphics g = Graphics.FromImage(bmp))
     8             {
     9                 //创建画笔
    10                 using (Font font = new Font(FontFamily.GenericSerif, 30))
    11                  {
    12                       //在100,100处画一个红色的helloWorld
    13                       g.DrawString("HelloWorld", font, Brushes.Red, 100, 100);
    14                       //在100,100处画一个蓝色的椭圆
    15                       g.DrawEllipse(Pens.Blue, 100, 100, 100, 100);
    16                       //图片保存到输出流  
    17                       bmp.Save(context.Response.OutputStream, ImageFormat.Jpeg);          
    18 
    19                  }
    20             } 

    clipboard[2]

    简单的数字验证码

    1.思维

    既然我们已经解决了如何动态生成图片,和如何在一般处理程序中返回一个图片的问题。

    那么做验证码的技术问题,只剩下了如何生成四位随机数了。

    其实就是用Random生成 1000~9999之间的随机数。

    然后把这个四位数放到Session中,在根据这个数字生成验证码图片。

    这就是生成验证码的基础逻辑了。

    2.代码

     1 public void ProcessRequest(HttpContext context)
     2         {
     3             context.Response.ContentType = "image/jpeg";
     4           
     5             Random random = new Random();
     6             //生成随机数
     7             string code = random.Next(1000, 9999).ToString();
     8             //把验证码放到Session中,方便以后比对
     9             context.Session["checkCode"] = code;
    10             //开始生成验证码的图片
    11             using (Bitmap bmp = new Bitmap(130, 50))
    12             using (Graphics g = Graphics.FromImage(bmp))
    13             {
    14                 using (Font font = new Font(FontFamily.GenericSerif, 30))
    15                 {
    16                     g.DrawString(code, font, Brushes.AliceBlue, 10, 10);
    17                     //图片保存到输出流 
    18                     bmp.Save(context.Response.OutputStream, ImageFormat.Jpeg);
    19                 }
    20             } 
    21         }

    生成效果(当然这样的验证码,稍微懂一点图形学的人都能用程序读取出来,开发中千万别这么干!)

    clipboard[3]

    3.节外生枝

    本来我敲着代码唱这歌,挺happy的,结果突然就给我报了一个空引用的异常,这里有必要说一下。

    看来有必要写一篇文章,详细的介绍一下Session,给自己好好补补课,补到她好我也好为止。

    clipboard[4]

     

    稍微复杂一点的验证码

    1.思路

    上面的验证码太简陋了,现在说一个稍微复杂一点的。

    我的改进思路是这样的。

    1)既然随机生成数字太简单,觉得说不过去。那就随机生成5个字符。

    字符写在一个数组里。随机生成数组下标,然后拿出五个。字符数组我们可以写的复杂一点。

    2)生成图片以后,在图片上随手扔点躁点,增加其他程序的识别成本。

    2.代码

     1 public void ProcessRequest(HttpContext context)  
     2      {  
     3          string checkCode = GenCode(5);  // 产生5位随机字符  
     4          context.Session["Code"] = checkCode; //将字符串保存到Session中,以便需要时进行验证  
     5          System.Drawing.Bitmap image = new System.Drawing.Bitmap(70, 22);  
     6          Graphics g = Graphics.FromImage(image);  
     7          try  
     8          {  
     9              //生成随机生成器  
    10              Random random = new Random();  
    11              //清空图片背景色  
    12              g.Clear(Color.White);  
    13              // 画图片的背景噪音线  
    14              int i;  
    15              for (i = 0; i < 25; i++)  
    16              {  
    17                  int x1 = random.Next(image.Width);  
    18                  int x2 = random.Next(image.Width);  
    19                  int y1 = random.Next(image.Height);  
    20                  int y2 = random.Next(image.Height);  
    21                  g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);  
    22              }  
    23    
    24              Font font = new System.Drawing.Font("Arial", 12, (System.Drawing.FontStyle.Bold));  
    25              System.Drawing.Drawing2D.LinearGradientBrush brush =  new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2F, true);  
    26              g.DrawString(checkCode, font, brush, 2, 2);  
    27              //画图片的前景噪音点  
    28              g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);  
    29              System.IO.MemoryStream ms = new System.IO.MemoryStream();  
    30              image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);  
    31              context.Response.ClearContent();  
    32              context.Response.ContentType = "image/Gif";  
    33              context.Response.BinaryWrite(ms.ToArray());  
    34          }  
    35          finally  
    36          {  
    37              g.Dispose();  
    38              image.Dispose();  
    39          }  
    40      }  
    41    
    42 /// <summary>  
    43 /// 产生随机字符串  
    44 /// </summary>  
    45 /// <param name="num">随机出几个字符</param>  
    46 /// <returns>随机出的字符串</returns>
    47      private string GenCode(int num)  
    48      {  
    49          string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    50          char[] chastr = str.ToCharArray();  
    51          // string[] source ={ "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", "#", "$", "%", "&", "@" };  
    52          string code = "";  
    53          Random rd = new Random();  
    54          int i;  
    55          for (i = 0; i < num; i++)  
    56          {  
    57              //code += source[rd.Next(0, source.Length)];  
    58              code += str.Substring(rd.Next(0, str.Length), 1);  
    59          }  
    60          return code;  
    61      }

    生成效果。差不多能用了吧?  

    clipboard[5]

    好了今天的关于验证码的问题就说这些了。

    我还是那个观点,这种东西没有必要记住,当然如果真能上手就写,那自然是极好的。

    记不住也不影响开发,写的时候上网搜一下就好了。

    之所以要写这篇文章有两个原因。

    1) 总要有人写这种东西,要不去哪复制。自己写一篇以后也好找。

    2) 毫无了解的代码,即使复制下来就能用,但是使用起来是心虚的。

    (当然这一点不绝对,太难的东西就算了。还是有太多东西我们是,不需要了解的。

     

      

  • 相关阅读:
    .csproj文件
    堆栈
    数据库操作(一)
    Math数学函数
    SSM框架下各个层的解释说明
    MyBatis DAO层传递参数到mapping.xml
    Spring MVC3在controller和视图之间传递参数的方法
    注册/登陆界面验证码的作用及代码实现
    input中name和id的区别
    <mvc:default-servlet-handler/>的作用
  • 原文地址:https://www.cnblogs.com/mcad/p/4352848.html
Copyright © 2020-2023  润新知