【转】开发基于ASP.NET WebService的图片验证码服务

2023-11-16

原文地址:http://www.webjx.com/htmldata/2006-01-21/1137824356.html

最近,工作中接到一项任务,开发一个页面验证码功能,查阅了一些网上的资料,并结合以前的绘图方面的知识,实现了如下的解决方案。生成的验证码效果如图:

开发基于ASP.NET WebService的图片验证码服务

  要解决的问题:

  1. 如何随机生成图片

    生成System.Drawing.Bitmap对象,使用System.Drawing.Graphics向位图对象中绘图。

  2. 如何在WebService的方法中通过参数传递图片数据

    将Bitmap对象输出成字节流,WebMothod使用字节数组返回该字节流。

  实例:

  1. 用VS.NET 2003创建一个ASP.NET Webservice工程,默认的Service名为MyService,为MyService添加一个名为GenerateVerifyImage的WebMethod。该方法的代码如下:

  /// <summary>
  /// 生成图片验证码
  /// </summary>
  /// <param name="nLen">验证码的长度</param>
  /// <param name="strKey">输出参数,验证码的内容</param>
  /// <returns>图片字节流</returns>
  [WebMethod]
  public byte[] GenerateVerifyImage(int nLen,ref string strKey)
  {
   int nBmpWidth = 13*nLen+5;
   int nBmpHeight = 25;
   System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(nBmpWidth,nBmpHeight);

   // 1. 生成随机背景颜色
   int nRed,nGreen,nBlue;  // 背景的三元色
   System.Random rd = new Random((int)System.DateTime.Now.Ticks);
   nRed = rd.Next(255)%128+128;
   nGreen = rd.Next(255)%128+128;
   nBlue = rd.Next(255)%128+128;

   // 2. 填充位图背景
   System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bmp);
   graph.FillRectangle(new SolidBrush(System.Drawing.Color.FromArgb(nRed,nGreen,nBlue))
    ,0
    ,0
    ,nBmpWidth
    ,nBmpHeight);


   // 3. 绘制干扰线条,采用比背景略深一些的颜色
   int nLines = 3;
   System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(nRed-17,nGreen-17,nBlue-17),2);
   for(int a =0;a< nLines;a++)
   {
    int x1 = rd.Next() % nBmpWidth;
    int y1 = rd.Next() % nBmpHeight;
    int x2 = rd.Next() % nBmpWidth;
    int y2 = rd.Next() % nBmpHeight;
    graph.DrawLine(pen,x1,y1,x2,y2);
   }

   // 采用的字符集,可以随即拓展,并可以控制字符出现的几率
   string strCode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";  

   // 4. 循环取得字符,并绘制
   string strResult = "";
   for(int i=0;i<nLen;i++)
   {
    int x = (i*13 + rd.Next(3));
    int y = rd.Next(4) + 1;

    // 确定字体
    System.Drawing.Font font = new System.Drawing.Font("Courier New",
     12 + rd.Next()%4,
     System.Drawing.FontStyle.Bold);
    char c = strCode[rd.Next(strCode.Length)];  // 随机获取字符
    strResult += c.ToString();

    // 绘制字符
    graph.DrawString(c.ToString(),
     font,
     new SolidBrush(System.Drawing.Color.FromArgb(nRed-60+y*3,nGreen-60+y*3,nBlue-40+y*3)),
     x,
     y);
   }

   // 5. 输出字节流
   System.IO.MemoryStream bstream = new System.IO.MemoryStream();
   bmp.Save(bstream,System.Drawing.Imaging.ImageFormat.Jpeg);
   bmp.Dispose();
   graph.Dispose();

   strKey = strResult;
   byte[] byteReturn = bstream.ToArray();
   bstream.Close();

   return byteReturn;
  }

  2. 测试WebMethod,添加一个WebForm,引用上述WebService,引用名为imagesvr。在Page_Load中添加代码:

   ...
   imagesvr.MyService imgsvr = new imagesvr.MyService();
   string strKey = "";
   byte[] data = imgsvr.GenerateVerifyImage(5,ref strKey);
   Response.OutputStream.Write(data,0,data.Length);
   ...

  3. 运行。每次refresh这个WebForm时,就会显示一个新生成的图片验证码,而函数的输出参数strKey保存的就是这个验证码的实际内容,可以保存在Session中,作为验证使用。

  上次开发出图片验证码之后,根据一些朋友的建议,本着验证码易识别(针对人),不易破解,美观的原则,改进了验证码生成的算法,采用图像滤镜的方法,对图片验证码进行反破解干扰,结果图片示例如下:

开发基于ASP.NET WebService的图片验证码服务

  滤镜效果主要采用波形(wave)算法,通过对X轴Y轴的正弦波形处理,产生叠加效果。算法主要描述如下:

  private const double PI = 3.1415926535897932384626433832795;
  private const double PI2 = 6.283185307179586476925286766559;

  /// <summary>
  /// 正弦曲线Wave扭曲图片
  /// </summary>
  /// <param name="srcBmp"></param>
  /// <param name="bXDir"></param>
  /// <param name="nMultValue">波形的幅度倍数</param>
  /// <param name="dPhase">波形的起始相位,取值区间[0-2*PI)</param>
  /// <returns></returns>
  public System.Drawing.Bitmap TwistImage(Bitmap srcBmp,bool bXDir,double dMultValue,double dPhase)
  {
   System.Drawing.Bitmap destBmp = new Bitmap(srcBmp.Width,srcBmp.Height);

   // 将位图背景填充为白色
   System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(destBmp);
   graph.FillRectangle(new SolidBrush(System.Drawing.Color.White),0,0,destBmp.Width,destBmp.Height);
   graph.Dispose();
  
   double dBaseAxisLen = bXDir ? (double)destBmp.Height : (double)destBmp.Width;

   for(int i=0;i<destBmp.Width;i++)
   {
    for(int j=0;j<destBmp.Height;j++)
    {
     double dx = 0;
     dx = bXDir ? (PI2*(double)j)/dBaseAxisLen : (PI2*(double)i)/dBaseAxisLen;
     dx += dPhase;
     double dy = Math.Sin(dx);

     // 取得当前点的颜色
     int nOldX = 0,nOldY = 0;
     nOldX = bXDir ? i + (int)(dy*dMultValue) : i;
     nOldY = bXDir ? j : j + (int)(dy*dMultValue);

     System.Drawing.Color color = srcBmp.GetPixel(i,j);
     if(nOldX >= 0 && nOldX < destBmp.Width
      && nOldY >=0 && nOldY < destBmp.Height)
     {
      destBmp.SetPixel(nOldX,nOldY,color);
     }
    }
   }

   return destBmp;
  }

  开头的示例图片,是两次波形效果的叠加,两次效果分别针对X轴方向和Y轴方向,如果取消对边缘背景色的填充,可以看到算法对图形的影响,如下图:

开发基于ASP.NET WebService的图片验证码服务

  这样产生的验证码,看起来很像Google站点上的验证码吧,当然,如果你有兴趣,还可以添加其他的滤镜效果,如拉伸,旋转,马赛克等。但是注意一点,网站验证码不是越复杂越好,要在速度和安全上找到一个平衡点。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【转】开发基于ASP.NET WebService的图片验证码服务 的相关文章

  • 当我的 Login.aspx 不在应用程序的根目录中时,如何使用 ASP.NET 登录控件?

    我正在使用ASP NET 登录控件 http msdn microsoft com en us library ms178329 aspx and 表单验证 http msdn microsoft com en us library aa4
  • Firefox 中的 Signalr 连接意外中止

    我正在使用 SignalR 具有跨域请求 2 3 0 版 用于集成到 ASP NET 站点的网络聊天 一切正常 但我发现 SignalR 连接的奇怪行为 当我单击聊天选项卡中的引用进行文件下载时 SignalR 连接被中止 并且在我的 Hu
  • ASP.Net 将 401 错误代码转换为 302 错误代码

    我有一个自定义处理程序 在某些情况下 我想向用户代理表明他们未获得授权 Http 错误代码 401 if IsAuthorized context context Response StatusCode 401 context Respon
  • 在 Windows 服务中调用 Web 服务

    我使用了一个简单的 Windows 服务来使一个方法在特定时间运行并且运行良好 接下来我已经尝试过 protected override void OnStart string args this WriteToFile Simple Se
  • 部分 ASP.NET MVC 视图提交

    我是 ASP NET MVC 的新手 所以这个问题可能显得 愚蠢 抱歉 我的主视图中有一个部分视图 部分视图提交一个表单 调用 HomeController 内的操作方法 它与服务器验证配合得很好 问题是在发布后仅呈现部分视图 发布后如何呈
  • 如何在Python中将字符串转换为包含一个元素的列表[重复]

    这个问题在这里已经有答案了 我有一个字符串 我想将其转换为其中只有一个元素的列表 a abc print list a output a b c Expected o p abc 正确的做法是什么 只需使用 a abc b a print
  • 在 Swift 中删除字符串中第一个字符的最简洁方法是什么?

    我想删除字符串中的第一个字符 到目前为止 我想到的最简洁的事情是 display text display text substringFromIndex advance display text startIndex 1 我知道我们不能用
  • 有没有办法将复选框列表绑定到 asp.net mvc 中的模型

    我在这里寻找一种快速简便的方法来在模型中发生回发时绑定复选框列表项的列表 显然现在常见的做法似乎是这样的form GetValues checkboxList 0 Contains true 这看起来很痛苦而且不太安全 有没有一种方法可以绑
  • Java中不同格式的字符串解析为日期

    我想转换String to Date以不同的格式 例如 我从用户那里得到 String fromDate 19 05 2009 i e dd MM yyyy format 我想转换这个fromDate作为日期对象 yyyy MM dd fo
  • 如何在 MVC5 中创建两种类型的用户?

    我正在创建 MVC5 应用程序 并且已经在使用 ASP NET Identity 来创建用户 因此 我已经有了 AspNetUsers 表 每当用户注册时 我都会在那里获得一个条目 我还有一个管理员角色 我可以手动指定哪个注册用户是管理员
  • 预编译的 asp.net 网站中的 - 这重要吗?

    我正在 Visual Studio 2008 上使用 Web 部署项目部署一个预编译和全页面合并的网站 请注意 所有程序集和项目都已在发布模式下编译 我的所有页面都是在发布模式下预编译的 所以它们不会被重新编译 它们只会被运行时加载 在不需
  • Java ArrayList 的 (ArrayList).toString 的相反是什么?

    我正在使用toString的方法ArrayList储藏ArrayList数据到字符串中 我的问题是 我该如何走另一条路 是否有现有的方法可以解析中的数据String实例返回到ArrayList 最简洁的答案是不 没有简单的方法可以从字符串中
  • 在运行时更改实体框架数据库架构

    在大多数 ASP NET 应用程序中 您可以通过在运行时修改连接字符串来更改数据库存储 即 我可以通过简单地更改连接字符串中 数据库 字段的值来从使用测试数据库更改为生产数据库 我正在尝试使用实体框架更改架构 但不一定是数据库本身 但没有成
  • 在 ASP.NET Core 中使用防伪功能并出现错误 - 防伪令牌无法解密

    我的 ASP Net Core MVC 应用程序已添加防伪中间件如下 启动 cs services AddMvc services AddSession services AddCaching services AddSession o g
  • asp.net 检查 imageURL 是否存在

    我正在尝试从另一个 Intranet 站点获取用户的缩略图 但其中一些不遵循预定义的格式 这意味着我想加载默认的缩略图 检查图像 URL 是否有效的最佳方法是什么 根据您获取图像的方式 此方法的变体可能会起作用 img src alt My
  • System.Linq.Dynamic 不支持 OrderByDescending("someColumn")?

    好的 在我们的项目中 我使用 System Linq Dynamic 库 但我刚刚注意到我无法执行以下操作 myDataSource OrderByDescending someColumnName 因为我收到以下错误 重载解析失败 因为无
  • ASP.NET DropDownList OnSelectedIndexChanged 事件未触发

    我试图同时使用一些 AJAX 和 ASP Net 来运行函数而无需刷新整个页面 但我在执行此操作时偶然发现了一个问题 这是我的代码
  • Asp.net core webapi获取从Angular4应用程序发布的空值

    我是新来的Angular4在快速交付内容的情况下 所以没有时间彻底学习它 所以如果我的问题看起来很幼稚 请原谅 From my Asp Net Web API I have Confirmemail API必须从 Angular4 应用程序
  • 会话变量由于某种原因丢失

    我尝试建立一个电子商店 每件物品旁边都有一个asp imagebutton单击此图像按钮时 我正在检查会话变量是否session basket 是否存在 如果不存在 则我将值添加到列表 实体类 中 然后在会话中添加此列表 如果会话不为空 那
  • ASP.NET GridView 默认排序顺序

    我有一个绑定到 sql 数据源的简单 gridview 控件 现在我启用了排序 但是当我单击要排序的列时 它首先按升序对其进行排序 当我再次单击同一列时 它会按降序排序 我想改变这一点 我希望它在第一次单击时按降序排序 在第二次单击时按升序

随机推荐

  • 表单页面美化(html、css)

    表单页面美化 html css 效果图片 实现代码 html部分就是平常的输入框 div class mainfont h1 在线预约 h1 div div class form div
  • OSW

    OSWatcher 工具 下载文档 Metalink Doc ID 301137 1 Oswatcher 主要用于监控主机资源 如CPU 内存 网络以及私有网络等 其中私有网络需要单独配置 需要说明的执行OSWatcher用户需要常见OS
  • 密码学概述

    一 密码学的起源与发展 密码学英文名称为Cryptography 密码学最为一门学科 是最近几十年开始迅速被人们重视和发展起来的 密码学往往与信息安全四个字精密的联系着 最早的密码学的 始祖 可以说是早在公元前几百年就已经出现了 当然 当时
  • 使用JDWP远程debug

    JDWP JDWP是Java Debug Wire Protocol 的缩写 它 定义了调试器 debugger 和被调试的Java虚拟机 target vm 之间的通信协议 SpringBoot debug 1 springboot框架搭
  • detr复现

    https github com IDEA Research detrex 先跑通 相关原理和代码后续解读
  • springboot不同版本整合elasticsearch

    使用springboot整合elasticsearch时候 需要注意版本的对应关系 不然问题会非常多 对应关系如下 springboot2 1整合 elasticsearch的两个方式 通过spring data es springboot
  • Typora软件下载与安装及使用技巧(保姆式教学)

    Typora的下载安装 当前 Typora 是一款支持实时预览的 Markdown 文本编辑器 深受广大程序员的喜爱 简洁明了 方便操作 下面来讲一下它的详细下载安装过程叭 下载安装过程 Typora的下载官网 https typoraio
  • 微信小程序云开发上传图片无法预览显示

    这是图片无法预览显示的情况 而且文件格式显示也不显示为图片格式 不要忘记要在起完名字后加上你希望的图片格式后缀名 加完之后就可以正常显示了
  • Linux链接脚本lds概述

    一 概论 ld 用来把一定量的目标文件跟档案文件链接在一起 并重新定位它们的数据 链接符号引用 一般编译一个程序时 最后一步就是运行ld进行链接 每一个链接过程都由链接脚本 linker script 一般以lds作为文件的后缀名 控制 链
  • 说说你对Object.defineProperty()的理解

    代码在最后 定义 Object defineProperty 方法会直接在一个对象上定义一个新属性 或者修改一个对象的现有属性 并返回此对象 Object defineProperty obj prop descriptor obj 要定义
  • Python糖尿病人预测是否患癌症

    Python糖尿病人预测是否患癌症 统计回归分析的任务 就在于根据x1 x2 x3 xp线性回归和Y的观察值 去估计函数f 寻求变量之间近似的函数关系 我们常用的是 假定f函数的数学形式已知 其中若干个参数未知的观察值去估计未知的参数值 这
  • 网马解密初级篇

    一 网页挂马的概念 网页挂马是指 在获取网站或者网站服务器的部分或者全部权限后 在网页文件中插入一段恶意代码 这些恶意代码主要是一些包括IE等漏洞利用代码 用户访问被挂马的页面时 如果系统没有更新恶意代码中利用的漏洞补丁 则会执行恶意代码程
  • nodejs egg框架统一错误信息返回封装

    use strict app middleware error handler js module exports gt return async function errorHandler ctx next try await next
  • ubuntu内网安装软件

    在生产环境中很少有连接外网的服务器 这里以ansible内网安装为例来介绍 1 安装ansible 有外网 1 ansible的安装包存在于ansible的PPA中 如果要下载PPA 个人软件包存档 就必须要使用apt add reposi
  • C++三角函数计算及弧度制角度制转换

    c 中所有三角函数计算里都是弧度制 用acos算出的弧度t转化为角度的时候 需要t 180 Pi 相对应的 角度换弧度需要t Pi 180 反三角函数 double acos double asin double atan
  • linux怎么看sdb1里面的文件,linux – 什么是sda,sdb,dm-0,dm-1的文档

    如果我运行iostat 我得到了 sda0 sda1 我知道那些是 硬盘 那么有dm 0 dm 1 我想查看文档 我的mount命令也显示了这个 dev mapper VolGroup lv root ext4 usrjquota quot
  • 数据库系统概论(章节重点)

    单词错误 有些地方说的也不是很严谨 大家稍微参考一下即可 祝大家期末顺利 数据库考试重点 题型 30分客观题 20选择10填空或反过来 覆盖面大 关系代数 70分主观题 简答 4 6个理论部分例如简述数据库设计步骤 编程 20 30分 设计
  • input的onchange事件实际触发条件与解决方法

    input中onchange事件已经属于元老级别了 并且现在同onclick一样使用频率很高 然而onchange的机制实际上有很多童鞋并不清楚 我们通过实例来分析这个事件的特征 触发onchange 首先页面有一个input标签 并且已绑
  • python 多线程 线程池的四种实现方式

    python 线程池的四种实现方式 线程简述 一个程序运行起来后 一定有一个执行代码的东西 这个东西就是线程 一般计算 CPU 密集型任务适合多进程 IO密集型任务适合多线程 一个进程可拥有多个并行的 concurrent 线程 当中每一个
  • 【转】开发基于ASP.NET WebService的图片验证码服务

    原文地址 http www webjx com htmldata 2006 01 21 1137824356 html 最近 工作中接到一项任务 开发一个页面验证码功能 查阅了一些网上的资料 并结合以前的绘图方面的知识 实现了如下的解决方案