[转] ASP.NET1.1(C#)中验证码产生的原理及应用

实现原理:
通过随机函数产生验证码元素,将数值型的验证码元素转换成字符型然后再连成字符串,将验证码字符串写入Cookie以供验证时调用。
通过后台动态绘制位图的方法,绘制一个指定大小的位图,然后在空白位图画出底纹、验证码字体、和边框。

实现代码
(1)Login.aspx(登录页前台)
<%@ Page language="c#" Codebehind="Login.aspx.cs" AutoEventWireup="false" Inherits="Validator.Login" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
    
<HEAD>
        
<title>Login</title>
        
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
        
<meta name="CODE_LANGUAGE" Content="C#">
        
<meta name="vs_defaultClientScript" content="JavaScript">
        
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
    
</HEAD>
    
<body MS_POSITIONING="GridLayout">
        
<form id="Form1" method="post" runat="server">
            
<asp:button id="Button1" style="Z-INDEX: 101; LEFT: 128px; POSITION: absolute; TOP: 64px" runat="server"
                Width
="96px" Text="提交"></asp:button>
            
<IMG src="CheckCode.aspx">
            
<asp:label id="lblMessage" style="Z-INDEX: 102; LEFT: 16px; POSITION: absolute; TOP: 128px"
                runat
="server"></asp:label>
            
<asp:textbox id="txtCheckCode" style="Z-INDEX: 103; LEFT: 16px; POSITION: absolute; TOP: 64px"
                runat
="server" Width="88px"></asp:textbox>
        
</form>
    
</body>
</HTML>

(2)Login.aspx.cs(登录页后台)
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace Validator
{
    
/// <summary>
    
/// Login 的摘要说明。
    
/// </summary>

    public class Login : System.Web.UI.Page
    
{
        
protected System.Web.UI.WebControls.Button Button1;
        
protected System.Web.UI.WebControls.Label lblMessage;
        
protected System.Web.UI.WebControls.TextBox txtCheckCode;
    
        
private void Page_Load(object sender, System.EventArgs e)
        
{
            
// 在此处放置用户代码以初始化页面
        }


        
Web 窗体设计器生成的代码

        
private void Button1_Click(object sender, System.EventArgs e)
        
{
            
if(Request.Cookies["CheckCode"== null
            
{
                lblMessage.Text 
= "您的浏览器设置已被禁用 Cookies,您必须设置浏览器允许使用 Cookies 选项后才能使用本系统。";
                lblMessage.Visible 
= true;
                
return;
            }

            
if(String.Compare(Request.Cookies["CheckCode"].Value, txtCheckCode.Text, false!= 0//参数为false时为区分大小写
            {
                lblMessage.Text 
= "验证码错误,请输入正确的验证码。";
                lblMessage.Visible 
= true;
                
return;
            }
 
            
else 
            
{
                lblMessage.Text 
= "通过验证";
                lblMessage.Visible 
= true;
                
return;
            }

        }

    }

}


(3) CheckCode.aspx(验证页前台)
<%@ Page language="c#" Codebehind="CheckCode.aspx.cs" AutoEventWireup="false" Inherits="Validator.CheckCode" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > 

<html>
  
<head>
    
<title>CheckCode</title>
    
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
    
<meta name="CODE_LANGUAGE" Content="C#">
    
<meta name=vs_defaultClientScript content="JavaScript">
    
<meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5">
  
</head>
  
<body MS_POSITIONING="GridLayout">
    
    
<form id="Form1" method="post" runat="server">
        
<FONT face="宋体"></FONT>
    
</form>
    
  
</body>
</html>

(4)CheckCode.aspx.cs(验证页后台)
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace Validator
{
    
/// <summary>
    
/// CheckCode 的摘要说明。
    
/// </summary>

    public class CheckCode : System.Web.UI.Page
    
{
        
private void Page_Load(object sender, System.EventArgs e)
        
{
            
// 在此处放置用户代码以初始化页面
            this.CreateCheckCodeImage(GenerateCheckCode());
        }


        
Web 窗体设计器生成的代码

        
private string GenerateCheckCode()
        
{                      
            
int number;                      
            
char code;                      
            
string checkCode = String.Empty;                                   
            System.Random random 
= new Random();                       
            
for(int i=0; i<5; i++)                      
            
{   //随机产生一个整数                             
                number = random.Next();                 
                
//如果随机数是偶数 取余选择从[0-9]                             
                if(number % 2 == 0)                                    
                    code 
= (char)('0' + (char)(number % 10));                             
                
else                             
                
//如果随机数是奇数 选择从[A-Z]                                    
                    code = (char)('A' + (char)(number % 26));                              
                    checkCode 
+= code.ToString();                      
            }
                       
            Response.Cookies.Add(
new HttpCookie("CheckCode", checkCode));                       
            
return checkCode;               
        }
         

        
//建立一个随机图形               
        private void CreateCheckCodeImage(string checkCode)               
        
{                      
            
if(checkCode == null || checkCode.Trim() == String.Empty)                             
                
return;             
            
//建立一个位图文件 确立长宽                                       
            System.Drawing.Bitmap image = new System.Drawing.Bitmap((int)Math.Ceiling((checkCode.Length * 12.5)), 22);                      
            Graphics g 
= Graphics.FromImage(image);                       
            
try                      
            
{                             
                
//生成随机生成器                             
                Random random = new Random();                              
                
//清空图片背景色                             
                g.Clear(Color.White);                              
                
//画图片的背景噪音点                             
                for(int i=0; i<60; i++)                             
                
{                                    
                    
int x = random.Next(image.Width);                                    
                    
int y = random.Next(image.Height);                                     
                    image.SetPixel(x, y, Color.FromArgb(random.Next()));                             
                }
                 
                
//把产生的随机数以字体的形式写入画面                             
                Font font = new System.Drawing.Font("Arial"12, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic));                             
                System.Drawing.Drawing2D.LinearGradientBrush brush 
= new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(00, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2ftrue);                             
                g.DrawString(checkCode, font, brush, 
22);                              
                
//画图片的边框线                             
                g.DrawRectangle(new Pen(Color.Silver), 00, image.Width - 1, image.Height - 1);                              
                System.IO.MemoryStream ms 
= new System.IO.MemoryStream();                             
                image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);                             
                Response.ClearContent();                             
                Response.ContentType 
= "image/Gif";                             
                Response.BinaryWrite(ms.ToArray());                      
            }
                      
            
finally                      
            
{                             
                g.Dispose();                             
                image.Dispose();                      
            }
               
        }

    }

}



主要函数分析:
1、通过随机函数(Random)先产生验证码组成元素(这里为五位) 并将其转换为字符串(属性为只读),完成后写入“Cookie”中去以供验证时调用。
2、将验证码字符串写入图形:
(1)建立一个位图文件确定长和宽:
System.Drawing.Bitmap image = new System.Drawing.Bitmap((int)Math.Ceiling((checkCode.Length * 12.5)), 22);
(a)System.Drawing. [C#] Bitmap(int width,int height);
(b)double Math.Ceiling (double a):返回大于或等于指定数字的最小整数。
(2)画图片的背景噪音点(60个):
for(int i=0; i<60; i++)  {
int x = random.Next(image.Width);
int y = random.Next(image.Height);
image.SetPixel(x, y, Color.FromArgb(random.Next()));
}
(a) public virtual int Next(int maxValue);返回一个小于所指定最大值的非负随机数。 参数:maxValue-要生成的随机数的上限。maxValue 必须大于或等于零。
(b) image.SetPixel(int x,int y,Color color); 参数: x-要设置的像素的 x 坐标;y-要设置的像素的 y 坐标;color-Color 结构,它表示要分配给指定像素的颜色。
(c) Color.FromArgb(int argb) 参数:argb-指定 32 位 ARGB 值的值。
(3)把产生的随机数以字体的形式写入位图:Graphics.DrawString(string s,Font font,Brush brush,float x,float y);
参数:s-要绘制的字符串;font-Font 对象,它定义字符串的文本格式;
brush-Brush 对象,它确定所绘制文本的颜色和纹理;
x-所绘制文本的左上角的 x 坐标;
y-所绘制文本的左上角的 y 坐标。(在指定位置并且用指定的 Brush 和 Font 对象绘制指定的文本字符串)
(4) 画图片的边框线: public void DrawRectangle(Pen pen, int x, int y, int width, int height);绘制由坐标对、宽度和高度指定的矩形。
参数:pen-Pen 对象,它确定矩形的颜色、宽度和样式;
x-要绘制的矩形的左上角的 x 坐标;
y-要绘制的矩形的左上角的 y 坐标;
width-要绘制的矩形的宽度;height-要绘制的矩形的高度。
(5) 将图片以二进制流的方式输出加上格式并可显示出来。
posted @ 2007-06-10 09:13  temptation  阅读(1078)  评论(0编辑  收藏  举报