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

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

科普一下,什么是GDI+?

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

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

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

        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());//输出二进制数据流
        }

生成的效果是这样的:

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

        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());//输出二进制数据流
        }

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

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

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

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

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

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

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

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

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

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

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

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

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

时间: 2024-08-28 19:17:40

ASP.NET 如何做出简单的验证码的相关文章

ASP.NET与Silverlight简单对比

最近在用ASP.NET做一个简单的网站,页面不算多,就是对一些数据的增删查改,美工方面也不需要我多考虑. 以前上学的时候,其实已经做过网站什么的了,做过个博客系统,模仿过开心网的部分功能.用ASP.NET做网站并不算陌生了.工作之后一直在使用Silverlight,初步学的时候就感觉好简单,连接好数据库后,建立模型,底层的一切ok,自己写一些操作就可以了,这么舒服一年后,我再用ASP.NET做网站,感觉好麻烦啊.可能是我没用体会到ASP.NET的强大吧. 1. ASP.NET中的对象类,我得自己

ASP.NET在实际开发中验证码的用法

在网上有看到很多关于验证码的代码,很多都只是生成一张验证码图片,然而在实际登陆验证模块,验证码要怎么添加进去或者说怎么运用.和实际项目开发中要怎么使用验证码,我自己总结了几点. 一.在实际开发登陆模块的验证码,程序员是将验证码的文本值(字符串)存在Session中的,然后在登陆验证的时候,通过Session取值进行判断的,这样效率会高很多. 二.然而在写验证码的时候要想通过Session存值,就必须实现System.Web.SessionState.IRequiresSessionState这个

asp.net MVC最简单的增删查改!(详)

折腾了两天搞出来,但原理性的东西还不是很懂,废话不多说上图上代码 然后右键models,新建一个数据模型 注意我添加命名为lianxi 添加后如上 接下来在controllers添加控制器还有在Views中添加视图 注意控制器lianxi和视图的名字要一致,然后视图我是添加了3个分别是Index,insert,Modify,在控制器里分别有三个对应的函数 每当用URL访问视图时,他就调用了controllers对应的方法,例如 jiaEntities 就是建立模式时那个数据链接的名字      

Asp.Net+Oracle+EasyUI简单增删查改

Asp.Net+Oracle+EasyUI简单增删查改 概要:网上有很多关于EasyUI前端框架的资料,本人在学习的基础上,基于自己之前搭建的框架(Oracle+Ado.Net),配合EasyUI实现一套简单的增删查改. 正文: 在实体层新建一个EMP.cs,继承至BaseModel 1 namespace myOracle.Model 2 { 3 public class Emp:BaseModel 4 { 5 public Emp() 6 { 7 base.PrimaryKey = "emp

简单制作验证码和绘制图片

今天仍然是完善一般处理程序小项目,但是昨天小小的项目已经终结,今天只是完善一下新的样式罢啦,嘿嘿,我们通常在网上浏览图片时间都会看到图片上面呈现有水印字体的样式,其实这些图片都是通过一些简单的小技术来修饰的:另外我们现在在网上随处可见注册页面,当我们想在一个网站上面注册新的用户时间,需要注册完信息以后填写随机生成的验证码,或者我们想要登录一个网站时间也需要验证码的填写,由此可见,验证码也是我们程序员需要必备的小技术哦,下面就来总结一下这两项小功能的实现. 一.图片上的水印字体 我们可以看到第一张

解析最简单的验证码

最近在学python,正好遇到学校需要选宿舍,就用python写了一个抢宿舍的软件.其中有一个模块是用来登陆的,登陆的时候需要输入验证码,不过后来发现了直接可以绕过验证码直接登陆的bug.不过这是另外的话题,开始的时候我并没有发现这个隐藏起来的秘密,所以我就写了这个python代码段用来实现解析验证码的功能. 我们学校的验证码是最简单的验证码,形式大概如下: 其中这个图片的大小是60X24像素的,大概每个数字的大小是15X24像素. 观察这个验证码之后可以发现,验证码中只有数字而且数字的字体很规

学习笔记:利用GDI+生成简单的验证码图片

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 学习笔记:利用GDI+生成简单的验证码图片 1 /// <summary> 2 /// 单击图片时切换图片 3 /// </summary> 4 /// <param name="sender">&

1小时ASP入门,非常简单

1小时ASP入门,非常简单 1小时ASP入门,非常简单. <%    语句    --   %> <2>定义变量dim语句 <%   dim a,b   a=10   b="ok!" %> 注意:定义的变梁蒙以是数值型,也可以是字符或者其他类型的 <3>简单的控制流程语句   1. If 条件1 then      语句1 elseif 条件2 then      语句2 else      语句3 endif 2.while 条件   

java实现生成简单图片验证码

原文:java实现生成简单图片验证码 源代码下载地址:http://www.zuidaima.com/share/1550463428840448.htm 项目载图: 该项目要转换为Dynamic web project http://www.zuidaima.com/blog/1618162161323008.htm 另外缺少jar包: http://www.zuidaima.com/jar/search/jstl-1.0.1.htm http://www.zuidaima.com/jar/s