详细说说如何生成验证码—ASP.NET细枝末节(4)
前言
今天小编详细的说一下,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)的更多相关文章
- ASP.NET ashx实现无刷新页面生成验证码
现在大部分网站登陆时都会要求输入验证码,在网上也看了一些范例,现在总结一下如何实现无刷新页面生成验证码. 效果图: 实现方式: 前台: <div> <span>Identify ...
- (一)【转】asp.net mvc生成验证码
网站添加验证码,主要为防止机器人程序批量注册,或对特定的注册用户用特定程序暴力破解方式,以进行不断的登录.灌水等危害网站的操作.验证码被广泛应用在注册.登录.留言等提交信息到服务器端处理的页面中. ...
- Asp.net mvc生成验证码
1.生成验证码类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...
- 012. asp.net生成验证码图片(汉字示例/字母+数字)
protected void Page_Load(object sender, EventArgs e) { //生成验证码图片的基本步骤 string checkCode = "新年快乐& ...
- Asp.net 生成验证码
生成验证码一般来说大体有这么几步: 1.生成验证码字符串,一般由四个或更多随机字符拼凑而成: 2.填充图片背景,并绘制图片的背景噪音线: 3.将验证码绘制到图片中: 4.绘制前景噪点: 5.返回图片流 ...
- ASP.NET MVC5 生成验证码
1 ValidateCode.cs using System; using System.Drawing; using System.Drawing.Drawing2D; using System.D ...
- 利用kaptcha生成验证码的详细教程
kaptcha是一个简单好用的验证码生成工具,有了它,你可以生成各种样式的验证码,因为它是可配置的.kaptcha工作的原理是调用 com.google.code.kaptcha.servlet.Ka ...
- 【转载】ASP.NET 生成验证码
直接上code using System; using System.Collections.Generic; using System.Linq; using System.Web; using S ...
- ASP.NET MVC 生成验证码
using System.Web.Mvc; using System.Drawing; using System; using System.Drawing.Imaging; using Models ...
随机推荐
- url传带有汉字的参数乱码解决
url传带有汉字的参数乱码解决 var reg = new RegExp("(^|&)createName=([^&]*)(&|$)"); var r = ...
- C# 事件总线 EventBus
1. 引言 事件总线这个概念对你来说可能很陌生,但提到观察者(发布-订阅)模式,你也许就很熟悉.事件总线是对发布-订阅模式的一种实现.它是一种集中式事件处理机制,允许不同的组件之间进行彼此通信而又不需 ...
- 第114天:Ajax跨域请求解决方法(二)
一.什么是跨域 我们先回顾一下域名地址的组成: http:// www . google : 8080 / script/jquery.js http:// (协议号) www (子 ...
- FZU2128_最长子串
题目说给你一个长串,要你选一个最长子串,不包括任何一个给定串为子串. 建立一个自动机,每个点保存的信息为当前这个状态为结尾最长可以有多长? 然后....就可以了... #include <ios ...
- C++解析(27):数组、智能指针与单例类模板
0.目录 1.数组类模板 1.1 类模板高效率求和 1.2 数组类模板 1.3 堆数组类模板 2.智能指针类模板 2.1 使用智能指针 2.2 智能指针类模板 3.单例类模板 3.1 实现单例模式 3 ...
- JAVA里面"=="和euqals的区别
(1)基本数据类型,用双等号“==”比较,比较的是他们的值,值类型是存储在内存中的栈中 (2)复合数据类型中, 当他们用“==”进行比较的时候,比较的是他们在内存中的存放地址,其变量在栈中仅仅是存储引 ...
- Qt消息机制和事件
Qt消息机制和事件 1 事件 事件(event)是由系统或者 Qt 本身在不同的时刻发出的.当用户按下鼠标.敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件.一些事件在对用户操作做出响应 ...
- 【刷题】洛谷 P3806【模板】点分治1
题目背景 感谢hzwer的点分治互测. 题目描述 给定一棵有n个点的树 询问树上距离为k的点对是否存在. 输入输出格式 输入格式: n,m 接下来n-1条边a,b,c描述a到b有一条长度为c的路径 接 ...
- 十大最佳Leap Motion体感控制器应用
十大最佳Leap Motion体感控制器应用 Leap Motion Controller也许还没有准备好大规模的发售,但是毫无疑问,这款小巧的动作捕捉器是我们见过的最酷的设备之一.这款设备的硬件 ...
- 洛谷 P1858 多人背包 解题报告
P1858 多人背包 题目描述 求01背包前k优解的价值和 输入输出格式 输入格式: 第一行三个数\(K\).\(V\).\(N\) 接下来每行两个数,表示体积和价值 输出格式: 前k优解的价值和 说 ...