前言

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

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

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

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

1.为啥要研究这东西?

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

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

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

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

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

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

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

2.学习流程

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

那么我们开始

一个简单的GDI小案例

1.说明

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

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

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

2.代码

             //这段代码开始前,要添加System.Drawing的引用。
//创建一个尺寸为500*500的内存图片
using (Bitmap bmp = new Bitmap(, ))
//得到图片的画布
using (Graphics g = Graphics.FromImage(bmp))
{
//创建画笔
using (Font font = new Font(FontFamily.GenericSerif, ))
{
//在100,100处画一个红色的helloWorld
g.DrawString("HelloWorld", font, Brushes.Red, , );
//在100,100处画一个蓝色的椭圆
g.DrawEllipse(Pens.Blue, , , , ); using (Stream stream = File.OpenWrite(@"d:\2.jpg"))
{
bmp.Save(stream, ImageFormat.Jpeg);
}
}
}

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

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

1.说明

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

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

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

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

2.代码

             context.Response.ContentType = "image/jpeg";

             //这段代码开始前,要添加System.Drawing的引用。
//创建一个尺寸为500*500的内存图片
using (Bitmap bmp = new Bitmap(, ))
//得到图片的画布
using (Graphics g = Graphics.FromImage(bmp))
{
//创建画笔
using (Font font = new Font(FontFamily.GenericSerif, ))
{
//在100,100处画一个红色的helloWorld
g.DrawString("HelloWorld", font, Brushes.Red, , );
//在100,100处画一个蓝色的椭圆
g.DrawEllipse(Pens.Blue, , , , );
//图片保存到输出流
bmp.Save(context.Response.OutputStream, ImageFormat.Jpeg); }
}

简单的数字验证码

1.思维

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

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

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

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

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

2.代码

 public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "image/jpeg"; Random random = new Random();
//生成随机数
string code = random.Next(, ).ToString();
//把验证码放到Session中,方便以后比对
context.Session["checkCode"] = code;
//开始生成验证码的图片
using (Bitmap bmp = new Bitmap(, ))
using (Graphics g = Graphics.FromImage(bmp))
{
using (Font font = new Font(FontFamily.GenericSerif, ))
{
g.DrawString(code, font, Brushes.AliceBlue, , );
//图片保存到输出流
bmp.Save(context.Response.OutputStream, ImageFormat.Jpeg);
}
}
}

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

3.节外生枝

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

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

稍微复杂一点的验证码

1.思路

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

我的改进思路是这样的。

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

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

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

2.代码

 public void ProcessRequest(HttpContext context)
{
string checkCode = GenCode(); // 产生5位随机字符
context.Session["Code"] = checkCode; //将字符串保存到Session中,以便需要时进行验证
System.Drawing.Bitmap image = new System.Drawing.Bitmap(, );
Graphics g = Graphics.FromImage(image);
try
{
//生成随机生成器
Random random = new Random();
//清空图片背景色
g.Clear(Color.White);
// 画图片的背景噪音线
int i;
for (i = ; i < ; i++)
{
int x1 = random.Next(image.Width);
int x2 = random.Next(image.Width);
int y1 = random.Next(image.Height);
int y2 = random.Next(image.Height);
g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
} Font font = new System.Drawing.Font("Arial", , (System.Drawing.FontStyle.Bold));
System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(, , image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2F, true);
g.DrawString(checkCode, font, brush, , );
//画图片的前景噪音点
g.DrawRectangle(new Pen(Color.Silver), , , image.Width - , image.Height - );
System.IO.MemoryStream ms = new System.IO.MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
context.Response.ClearContent();
context.Response.ContentType = "image/Gif";
context.Response.BinaryWrite(ms.ToArray());
}
finally
{
g.Dispose();
image.Dispose();
}
} /// <summary>
/// 产生随机字符串
/// </summary>
/// <param name="num">随机出几个字符</param>
/// <returns>随机出的字符串</returns>
private string GenCode(int num)
{
string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char[] chastr = str.ToCharArray();
// 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", "#", "$", "%", "&", "@" };
string code = "";
Random rd = new Random();
int i;
for (i = ; i < num; i++)
{
//code += source[rd.Next(0, source.Length)];
code += str.Substring(rd.Next(, str.Length), );
}
return code;
}

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

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

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

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

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

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

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

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

详细说说如何生成验证码—ASP.NET细枝末节(4)的更多相关文章

  1. ASP.NET ashx实现无刷新页面生成验证码

    现在大部分网站登陆时都会要求输入验证码,在网上也看了一些范例,现在总结一下如何实现无刷新页面生成验证码. 效果图: 实现方式: 前台: <div> <span>Identify ...

  2. (一)【转】asp.net mvc生成验证码

    网站添加验证码,主要为防止机器人程序批量注册,或对特定的注册用户用特定程序暴力破解方式,以进行不断的登录.灌水等危害网站的操作.验证码被广泛应用在注册.登录.留言等提交信息到服务器端处理的页面中.   ...

  3. Asp.net mvc生成验证码

    1.生成验证码类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...

  4. 012. asp.net生成验证码图片(汉字示例/字母+数字)

    protected void Page_Load(object sender, EventArgs e) { //生成验证码图片的基本步骤 string checkCode = "新年快乐& ...

  5. Asp.net 生成验证码

    生成验证码一般来说大体有这么几步: 1.生成验证码字符串,一般由四个或更多随机字符拼凑而成: 2.填充图片背景,并绘制图片的背景噪音线: 3.将验证码绘制到图片中: 4.绘制前景噪点: 5.返回图片流 ...

  6. ASP.NET MVC5 生成验证码

    1 ValidateCode.cs using System; using System.Drawing; using System.Drawing.Drawing2D; using System.D ...

  7. 利用kaptcha生成验证码的详细教程

    kaptcha是一个简单好用的验证码生成工具,有了它,你可以生成各种样式的验证码,因为它是可配置的.kaptcha工作的原理是调用 com.google.code.kaptcha.servlet.Ka ...

  8. 【转载】ASP.NET 生成验证码

    直接上code using System; using System.Collections.Generic; using System.Linq; using System.Web; using S ...

  9. ASP.NET MVC 生成验证码

    using System.Web.Mvc; using System.Drawing; using System; using System.Drawing.Imaging; using Models ...

随机推荐

  1. Alpha冲刺阶段集合贴

    第一篇:http://www.cnblogs.com/xss6666/p/8870734.html 第二篇:http://www.cnblogs.com/xss6666/p/8893683.html ...

  2. 增加响应header让ajax支持跨域

    ajax请求数据步骤 发送请求--->浏览器接受响应--->判断是否是同域下 是的话,就把响应数据返回给ajax.不是的话就提醒禁止跨域请求. 现在可以在响应头重增加 header(&qu ...

  3. hash值

    任何类都继承public int hashCode()方法,该方法返回的值是通过将该对象的内部地址转换为一个整数来实现的,hash表的主要作用就是在对对象进行散列的时候作为key输入.我们需要每个对象 ...

  4. Android Studio -导入项目 gradle处理

    如果导入 android studio 项目, 那么一定要注意 需要合适的gradle版本,具体方法为: 首先导入步骤: 打开android studio ==> File ==> New ...

  5. J2EE十三种技术规范介绍

    J2EE的十三个技术规范 J2EE体系结构 一.JDBC:Java Data Base Connectivity,数据库连接 我们大家对微软公司的ODBC数据库访问接口比较熟悉,而在Java中创建数据 ...

  6. 【操作系统、UNIX环境编程】进程间通信

    多个进程可以共享系统中的各种资源,但其中许多资源一次只能为一个进程使用,我们把一次仅允许一个进程使用的资源称为临界资源,许多物理设备都属于临界资源,如打印机等. Linux下进程间通信有如下几种方式: ...

  7. BZOJ3573 HNOI2014米特运输

    显然确定一个点的权值后整棵树权值确定.只要算出根节点的权值就能知道两种改法是否等价. 乘的话显然会炸,取log即可.map似乎会出一些问题,sort即可. #include<iostream&g ...

  8. 关于upper、lower bound 的探讨

    lower_bound(A, A+n, x) - A  返回第一个大于等于x的数的下标 lower_bound(A, A+n, x) - A - 1 返回最后一个小于x的数的下标 upper_boun ...

  9. DjangoORM外键操作

    Django ORM 外键操作 经常修改的东西一般不放到内存里面,而是放到一张表里.表跟表之间是可以存在关系的,最基本的就是一对多的关系. models.ForeignKey(ColorDic) 1. ...

  10. 【刷题】LOJ 6041 「雅礼集训 2017 Day7」事情的相似度

    题目描述 人的一生不仅要靠自我奋斗,还要考虑到历史的行程. 历史的行程可以抽象成一个 01 串,作为一个年纪比较大的人,你希望从历史的行程中获得一些姿势. 你发现在历史的不同时刻,不断的有相同的事情发 ...