欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

如何使用ASP.NET制作简单的验证码

程序员文章站 2023-12-21 12:49:46
大家都知道验证码是以图片形式展示的,而且是动态生成的,这样就需要我们去画出它,那不得不提到是gdi+绘图了 科普一下,什么是gdi+? gdi+是图形设备接口(...

大家都知道验证码是以图片形式展示的,而且是动态生成的,这样就需要我们去画出它,那不得不提到是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());//输出二进制数据流
  }

生成的效果是这样的:

如何使用ASP.NET制作简单的验证码

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

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

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

如何使用ASP.NET制作简单的验证码

是不是看起来更专业一些了呢?如果大家还是觉得不满意的话,可以看下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去实现。大家可以自己试试。

以上就是本文给大家分享的制作验证码的全部过程,希望大家能够喜欢。

上一篇:

下一篇: