自己写的一个图形验证码页面(Asp.Net2.0通过)

本文示例代码
项目需要,要在首页登录界面添加一个图形验证码,赶时髦吧,网上一搜,特别多,找了几个,都不太满意。主要问题是大部分代码生成的图片宽度不唯一,页面布局不容易控制,其次是颜色单一,有些又过于抽象,不仔细看很容易弄错。针对特定的客户,我只需要“图片”长宽固定,颜色多样的数字图形验证码,借鉴网上的现有代码,自己操刀完成,以下是效果图:


原理不复杂,就是把网页当画布,运用各色画笔,在特定区域内画出数字,然后以特定格式(本例为PNG格式)发回客户端,在IE中显示为"图片",用于验证的字符串存于Session中。

主要代码如下:
//  生成随机数字字符串
public string GetRandomNumberString(int int_NumberLength)
{
    
string str_Number = string.Empty;
    Random theRandomNumber 
= new Random();

    
for (int int_index = 0; int_index < int_NumberLength; int_index++)
        str_Number 
+= theRandomNumber.Next(10).ToString();

    
return str_Number;
}

生成随机颜色
public Color GetRandomColor()
{
    Random RandomNum_First 
= new Random((int)DateTime.Now.Ticks);
    
//  对于C#的随机数,没什么好说的
    System.Threading.Thread.Sleep(RandomNum_First.Next(50));
    Random RandomNum_Sencond 
= new Random((int)DateTime.Now.Ticks);       

    
//  为了在白色背景上显示,尽量生成深色
    int int_Red = RandomNum_First.Next(256);
    
int int_Green = RandomNum_Sencond.Next(256);
    
int int_Blue = (int_Red + int_Green > 400? 0 : 400 - int_Red - int_Green;
    int_Blue 
= (int_Blue > 255? 255 : int_Blue;

    
return Color.FromArgb(int_Red, int_Green, int_Blue);
}

根据验证字符串生成最终图象
public void CreateImage(string str_ValidateCode)
{
    
int int_ImageWidth = str_ValidateCode.Length * 13;
    Random newRandom 
= new Random();
    
//  图高20px
    Bitmap theBitmap = new Bitmap(int_ImageWidth, 20);
    Graphics theGraphics 
= Graphics.FromImage(theBitmap);
    
//  白色背景
    theGraphics.Clear(Color.White);
    
//  灰色边框
    theGraphics.DrawRectangle(new Pen(Color.LightGray, 1), 00, int_ImageWidth - 119);
    
    
//  10pt的字体
    Font theFont = new Font("Arial"10);

    
for (int int_index = 0; int_index < str_ValidateCode.Length; int_index++)
    
{            
        
string str_char = str_ValidateCode.Substring(int_index, 1);
        Brush newBrush 
= new SolidBrush(GetRandomColor());
        Point thePos 
= new Point(int_index * 13 + 1 + newRandom.Next(3), 1 + newRandom.Next(3));
        theGraphics.DrawString(str_char, theFont, newBrush, thePos);
    }


    
//  将生成的图片发回客户端
    MemoryStream ms = new MemoryStream();
    theBitmap.Save(ms, ImageFormat.Png);

    Response.ClearContent(); 
//需要输出图象信息 要修改HTTP头 
    Response.ContentType = "image/Png";
    Response.BinaryWrite(ms.ToArray());
    theGraphics.Dispose();
    theBitmap.Dispose();
    Response.End();
}

最后在Page_Load中调用以上代码

private void Page_Load(object sender, System.EventArgs e)
{      
    
if(!IsPostBack)
    
{
        
//  4位数字的验证码
        string str_ValidateCode = GetRandomNumberString(4);
        
//  用于验证的Session
        Session["ValidateCode"= str_ValidateCode;
        CreateImage(str_ValidateCode);
    }

}

使用的时候在页面中加入一个Image,将图片路径改为ValidateCode.aspx的相对路径即可

<img src="ValidateCode.aspx" />
在需要验证的地方填入如下代码:
if (TextBox1.Text == Session["ValidateCode"].ToString())
{
    TextBox1.Text 
= "正确!";
}

else
    TextBox1.Text 
= "错误!";
OK,基本搞定,总结一下:
优点:1. 简单明了,适于简单运用
          2. 界面友好,图片长宽格式固定
缺点:1. 如果有多个页面都需要此验证码,则会导致Session被其它页面重写的情况,可以考虑指定具体Session值为效验值
         2. 暂时只支持数字,不过更改GetRandomNumberString()中的代码可以实现指定字符集的随机字符串
         3. 页面刷新后验证码随之改变

抛砖引玉,欢迎各位博友评点
posted @ 2006-07-27 01:30 nZAI 阅读(3404) 评论(23)  编辑 收藏

  回复  引用    
#1楼2006-09-12 00:56 | 清风[匿名][未注册用户]
怎么总是把随即生成的图片下载了阿??
不能够在浏览器中显示阿?
该怎么做啊?

  回复  引用  查看    
#2楼[楼主]2006-09-12 09:08 | nZAI      
@清风[匿名]
你的IE设置用启用了“显示图片”了吗?

  回复  引用    
#3楼2006-09-15 12:41 | good[未注册用户]
不错也!! 我的成功了!!非常感谢!
  回复  引用    
#4楼2006-10-06 15:24 | yxl[未注册用户]
不错 Ok
  回复  引用    
#5楼2006-10-14 20:38 | 菜鸟[匿名][未注册用户]
菜鸟提问了
D:\webfromcaozuo\WebForm1.aspx.cs(87): 找不到类型或命名空间名称“MemoryStream”(是否缺少 using 指令或程序集引用?)

D:\webfromcaozuo\WebForm1.aspx.cs(88): 名称“ms”在类或命名空间“baiweiping.WebForm1”中不存在)

D:\webfromcaozuo\WebForm1.aspx.cs(88): 找不到类型或命名空间名称“ImageFormat”(是否缺少 using 指令或程序集引用?)

D:\webfromcaozuo\WebForm1.aspx.cs(92): 找不到类型或命名空间名称“ms”(是否缺少 using 指令或程序集引用?)


还有<img src="ValidateCode.aspx" />这个在那里加呀?在HTML中那点加???

原因很简单,看的出来那里错了哈,不认识这个类型?怎么办?网上等。




  回复  引用    
#6楼2006-10-14 20:44 | 菜鸟[匿名][未注册用户]
加我的QQ嘛。直接给我说一下吧。116294188
  回复  引用  查看    
#7楼[楼主]2006-10-14 21:13 | nZAI      
你那个错误是缺少引用,可能你没看我给出的例子代码,里面的引用写的很清楚
查MSDN,在添上如下using
using System.Web.Security;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Configuration;

另外<img src="ValidateCode.aspx" />添加在要添加验证码的页面的HTML代码中,细节的地方你看我给出的例子http://www.cnblogs.com/Files/nzai/ValidateCode.rar">http://www.cnblogs.com/Files/nzai/ValidateCode.rar



  回复  引用    
#8楼2007-03-06 16:55 | rcok[未注册用户]
很不错啊,刚好派上用场,谢谢你啊 !!!
如何更改GetRandomNumberString()中的代码来实现指定字符集的随机字符串,敬请赐教!!



  回复  引用  查看    
#9楼[楼主]2007-03-06 17:17 | nZAI      
以下给出一个简单的例子,可以自己更改strCollection中的字符
注意using System.Text
 1//  生成随机数字字符串
 2public string GetRandomNumberString(int int_NumberLength)
 3{
 4    string strCollection = "1234567890ABCDEF";
 5    StringBuilder sbText = new StringBuilder();
 6    Random theRandomNumber = new Random();
 7
 8    for (int int_index = 0; int_index < int_NumberLength; int_index++)
 9        sbText.Append(strCollection[theRandomNumber.Next(strCollection.Length)].ToString());
10
11    return sbText.ToString();
12}

  回复  引用    
#10楼2007-05-18 14:47 | 六合彩[未注册用户]
hehe
  回复  引用    
#11楼2007-06-01 15:08 | 赤马[未注册用户]
System.Threading.Thread.Sleep(RandomNum_First.Next(50));
这句阻隔线程在这里起什么作用的?

  回复  引用    
#12楼2007-06-05 13:14 | polo[未注册用户]
我启用了 显示图片,还是只能显示下载图片,而不是把网页显示出来
  回复  引用    
#13楼2007-06-05 13:16 | polo[未注册用户]
只能在设计视图看到随即验证码
  回复  引用    
#14楼2007-07-06 10:46 | 吴[未注册用户]
只能在设计视图看到随即验证码
上面的那些代码放在什么地方下面啊~~~~????

  回复  引用    
#15楼2007-07-10 17:15 | test1[未注册用户]
if (TextBox1.Text == Session["ValidateCode"].ToString()) 如果这个Session的值超过5分钟以,那么Session["ValidateCode"]就是一个无效的对象,在程序运行时就会发生错误。
  回复  引用    
#16楼2007-07-17 13:52 | nZAI[未注册用户]
Session有一个有效期,可以在web.config子设置
  回复  引用    
#17楼2007-08-04 17:16 | 32[未注册用户]
有个问题
验证码这样是可以实现了
但是如果是一个整体网站,那么为了安全都会在web.config里面
配置整个网站的打开的初始页面,如login.aspx
即无论在网站地址栏输入这个网站什么样的连接
它都会默认先让用户登陆.
那么现在问题来了.

我是这样做的:
新建一个WEB用户控件customerlogin.ascx并且设计好页面和前台代码
在login.aspx中调用用户控件,
在WEB.CONFIG中配置初始页为login.aspx
那么运行,就出现问题了,login页面无法获取到验证码,即服务器没有执行验证码那个页面.我用SESSION获取验证吗显示获取的值为空.
即使我在验证码页面初始化用了
if(IsPostBack)
{
}
语句判断.
但还是不会执行这个页面.


我苦恼,自己还是什么都不会.
这个问题怎么解决,请高手帮忙

  回复  引用    
#18楼2007-08-04 21:34 | hdf[未注册用户]
这个验证码也太弱了,很容易就被别人程序识别出来了,

看看这个:
http://www.wfsoft.com/wf_wfVerifyImage.asp

验证码控件中的极品。

  回复  引用  查看    
#19楼[楼主]2007-09-13 01:11 | nZAI      
@hdf
请看清楚第一段文字再发表评论

  回复  引用    
#20楼2008-04-16 15:59 | dmr[未注册用户]
很好用,谢谢哈
  回复  引用  查看    
#21楼2008-07-23 10:21 | YuHui      
不错,学习一下
  回复  引用    
#22楼2008-08-17 10:42 | otouch[未注册用户]
不错哦,学习一下
  回复  引用    
#23楼2008-12-17 13:12 | lgh[未注册用户]
我想提个问..怎么可以实现点击验证码或者"看不清,换一张 "来刷新楼主做的验证码呢..我弄不了



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 460549




相关文章:

相关链接: