ASP.NET 如何做出简单的验证码

简介:

如果说要做验证码,那不得不提的就是GDI+绘图了。我们都知道验证码是以图片形式展示的,而且是动态生成的,这样就需要我们去画出它。

科普一下,什么是GDI+?

GDI+是图形设备接口(GDI)的高级版本, 提供了各种丰富的图形图像处理功能。GDI+主要由二维矢量图形、图像处理和版式3部分组成。GDI+为使用各种字体、字号和样式来显示文本这种复杂任务提供了大量的支持。

下面说说验证码,对于验证码这样的图片,我觉得是由两部分组成的,一部分是矩形的背景,另一部分是在其上的字母数字组合(有的时候有汉字,有的时候是纯字母或者纯数字,这个没有统一规定,怎么选择看你~)。对于矩形的背景我们可以直接把其当成画布,字母数字组合呢?我们可以利用随机数去拼出一组新组合。这样整个过程我们都想好了,下面看下代码吧:

声明一下,我写的这个验证码为5个字符长度,由大小写英文字母+数字随机组合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
         private  readonly  char [] constant =  {   
         '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' ,   
         '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' }; //一个由数字和大小写英文字母组成的字符数组
 
         protected  void  Page_Load( object  sender, EventArgs e)
         {
             Bitmap bitmap =  new  Bitmap(100, 25); //创建一个位图,宽100,高25,就是我所说的第一部分,矩形背景
             Graphics g = Graphics.FromImage(bitmap); //创建画布
             g.Clear(Color.YellowGreen); //为画布填充黄绿色
 
             Font font1 =  new  Font( "Arial" , 15); //设置字体类型和大小 
             Brush brush =  new  SolidBrush(Color.Blue); //设置画刷颜色
             Pen myPen =  new  Pen(Color.Blue, 5); //创建画笔对象
 
             StringBuilder random =  new  StringBuilder(5);  //创建可变字符串对象,用于存放随机生成的验证码
             Random rd =  new  Random(); //创建一个随机数生成器对象
             for  ( int  i = 0; i < random.Capacity; i++)
             {
                 random.Append(constant[rd.Next(62)]); //生成一个随机字符加到random里
             }
 
             g.DrawString(random.ToString(), font1, brush, 10, 5); //在画布上画出字符串
 
             System.IO.MemoryStream ms =  new  System.IO.MemoryStream(); //创建数据流MemoryStream
             bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Gif); //指定图像的输出格式为gif
 
             Response.ClearContent();
             Response.ContentType =  "image/Gif" ;
             Response.BinaryWrite(ms.ToArray()); //输出二进制数据流
         }

生成的效果是这样的:

wKiom1PXFVuBZu-6AAAS84ozNS4701.jpg

大家可能会觉得这样看起来很容易辨识,跟我们平时登录网站时输入的验证码比起来有点像个小学生。当然,我们可以做些改变,比较加上一定的角度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
         private  readonly  char [] constant =  {   
         '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' ,   
         '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' }; //一个由数字和大小写英文字母组成的字符数组
 
         protected  void  Page_Load( object  sender, EventArgs e)
         {
             Bitmap bitmap =  new  Bitmap(100, 25); //创建一个位图,宽100,高25,就是我所说的第一部分,矩形背景
             Graphics g = Graphics.FromImage(bitmap); //创建画布
             g.Clear(Color.YellowGreen); //为画布填充黄绿色
 
             Font font1 =  new  Font( "Arial" , 15); //设置字体类型和大小 
             float  angle = 60; //旋转的一个基础角度
             float  length = 0; //显示字符的基础位置,往后看
             Brush brush =  new  SolidBrush(Color.Blue); //设置画刷颜色
             Pen myPen =  new  Pen(Color.Blue, 5); //创建画笔对象
 
             StringBuilder random =  new  StringBuilder(5);  //创建可变字符串对象,用于存放随机生成的验证码
             Random rd =  new  Random(); //创建一个随机数生成器对象
             for  ( int  i = 0; i < random.Capacity; i++)
             {
                 random.Append(constant[rd.Next(62)]); //生成一个随机字符加到random里
 
                 g.ResetTransform(); //将画布重置矩阵
                 SizeF size = g.MeasureString(random[random.Length - 1].ToString(), font1); //得到新生成字符的尺寸
                 g.TranslateTransform(length + size.Width / 2, size.Height / 2); //选择此次旋转的中心位置
                 g.RotateTransform(( float )rd.NextDouble() * angle * 2 - angle); //进行随机角度旋转
                 g.DrawString(random[random.Length - 1].ToString(), font1, brush,  new  PointF(-size.Width / 2, -size.Height / 2)); //注意,这里不是前一个例子,一次性把5个字符全部画出来,而是一个一个画
                 length += size.Width; //保证下次画字符的位置不会覆盖前一次的字符
             }
 
             System.IO.MemoryStream ms =  new  System.IO.MemoryStream(); //创建数据流MemoryStream
             bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Gif); //指定图像的输出格式为gif
 
             Response.ClearContent();
             Response.ContentType =  "image/Gif" ;
             Response.BinaryWrite(ms.ToArray()); //输出二进制数据流
         }

这时生成的效果是这样的:

wKioL1PXFp-Q8odMAAAlOjRK5xA334.jpg

是不是看起来更专业一些了呢?如果大家还是觉得不满意的话,可以看下GDI+的相关内容,通过添加一些噪点的元素,或者删除线这样子的东西来达到提高识别难度的目的,我这里就不一一列举啦。

关于如何画验证码我们说过了,但是还有两点问题我还是想多说一下。

1、我们实际输出的是一个二进制的流,如何做到显示到页面上与页面其他元素共存呢?

这里通用的一种方法就是把画验证码的这段代码放到一个独立的Web窗体页中,在另一个需要显示验证码的页面放一个<img>元素,把其src属性指向该验证码页的url。比如我写的一段是这样

1
<asp:Image ID= "image_validatecode"  runat= "server"  ImageUrl= "~/PublicMethod/ValidateCode.aspx"  style= "padding-left:3px" />

其实这里我是用大家通用的方法,不过我先前也有单独写一个web自定义控件,专门生成验证码使用,但是当拖入到页面中后运行,它还是会把页面其他元素给覆盖掉,具体原因我也不清楚。

2、验证码主要目的还是用于验证使用的,所以我们在用户名,密码是否合法外,同时也要判断当前输入的验证码是不是与图片上的验证码一致。

我上面的代码中并没有写这块,其实只要在随机生成最终验证码之后,把其值存入一个session中去就可以了。然后在判断用户名,密码的同时去比较一下这个session值就OK了。如:

1
Session[ "login_validate_code" ] = random.ToString();

3、如何用户没有看清此张验证码,想换一张如何实现?

可以通过脚本给img元素的src属性重新赋值url实现,当然,麻烦点的话也可以使用ajax去实现。大家可以自己试试。










本文转自 我不会抽烟 51CTO博客,原文链接:http://blog.51cto.com/zhouhongyu1989/1532047,如需转载请自行联系原作者

目录
相关文章
|
7月前
|
开发框架 前端开发 JavaScript
盘点72个ASP.NET Core源码Net爱好者不容错过
盘点72个ASP.NET Core源码Net爱好者不容错过
167 0
|
7月前
|
开发框架 .NET
ASP.NET Core NET7 增加session的方法
ASP.NET Core NET7 增加session的方法
90 0
|
存储 开发框架 前端开发
asp.net与asp.net优缺点及示例
asp.net与asp.net优缺点及示例
|
4月前
|
开发框架 JSON .NET
ASP.NET Core 标识(Identity)框架系列(三):在 ASP.NET Core Web API 项目中使用标识(Identity)框架进行身份验证
ASP.NET Core 标识(Identity)框架系列(三):在 ASP.NET Core Web API 项目中使用标识(Identity)框架进行身份验证
|
4月前
|
开发框架 .NET 数据库连接
ASP.NET Core 标识(Identity)框架系列(一):如何使用 ASP.NET Core 标识(Identity)框架创建用户和角色?
ASP.NET Core 标识(Identity)框架系列(一):如何使用 ASP.NET Core 标识(Identity)框架创建用户和角色?
|
7月前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
|
7月前
|
SQL 开发框架 JavaScript
分享33个ASP.NET电子商务源码和40个ASP.NET控件组件源码,总有一款适合您
分享33个ASP.NET电子商务源码和40个ASP.NET控件组件源码,总有一款适合您
91 0
|
7月前
|
存储 开发框架 .NET
Asp.net就业课之Ado.net第一次课
Asp.net就业课之Ado.net第一次课
44 0
|
存储 开发框架 .NET
ASP.NET学生管理系统(.NET毕业设计)
ASP.NET学生管理系统(.NET毕业设计)
168 0
|
开发框架 前端开发 JavaScript
ASP .Net Core 中间件的使用(一):搭建静态文件服务器/访问指定文件
ASP .Net Core 中间件的使用(一):搭建静态文件服务器/访问指定文件