Beyond the dream——飛雪飄寒

————磨難不過是人生鍵盤的回車。。。。。。
  博客园  :: 首页  :: 联系 :: 订阅 订阅  :: 管理

.net实现验证码功能

Posted on 2009-01-22 11:36  飛雪飄寒  阅读(18660)  评论(20编辑  收藏  举报

  一、验证码简介
  验证码功能一般是用于防止批量注册的,不少网站为了防止用户利用机器人自动注册、登录、灌水,都采用了验证码技术。所谓验证码,就是将一串随机产生的数字或字母或符号或文字,生成一幅图片, 图片里加上一些干扰象素(防止OCR),由用户肉眼识别其中的验证码信息,输入表单提交网站验证,验证成功后才能使用某项功能。

  常见的验证码有如下几种: 
  1、纯数字验证码,一般为四位随机数字;
  2、数字+字母验证码,一般从数字(0~9)和字母(A~Z和a~z)中随机抽出几个字符组成;
  3、汉字验证码,相对而言,这种验证码比较少见一点,实现起来也相对复杂一些,但在不少网站中还是可以看到的;

  二、验证码的实现
  1、纯数字验证码的实现
  
纯数字验证码的实现相对比较简单,可通过以下两种方法来实现
  (1)使用随机数方式,代码如下: 

        private String GetRandomint(int codeCount)
        {
            Random random 
= new Random();
            
string min = "";
            
string max = "";
            
for (int i = 0; i < codeCount; i++)
            {
                min 
+="1";
                max
+="9";
            }
                
return (random.Next(Convert.ToInt32(min),Convert.ToInt32(max)).ToString());
        }


   (2)使用随机组合方式,代码如下:

        private string CreateRandomCode(int codeCount)
        {
            
string allChar = "0,1,2,3,4,5,6,7,8,9"
            
string[] allCharArray = allChar.Split(','); 
            
string randomCode = ""
            
int temp = -1
            Random rand 
= new Random(); 
            
for (int i = 0; i < codeCount; i++
            { 
                
if (temp != -1
                { 
                    rand 
= new Random(i * temp * ((int)DateTime.Now.Ticks)); 
                } 
                
int t = rand.Next(9); 
                
if (temp == t) 
                { 
                    
return CreateRandomCode(codeCount); 
                } 
                temp 
= t; 
                randomCode 
+= allCharArray[t]; 
            } 
            
return randomCode;
        }


  2、数字+字母验证码的实现,代码如下:

        private string CreateRandomCode(int codeCount)
        {
            
string allChar = "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,W,X,Y,Z,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[] allCharArray = allChar.Split(','); 
            
string randomCode = ""
            
int temp = -1
            Random rand 
= new Random(); 
            
for (int i = 0; i < codeCount; i++
            { 
                
if (temp != -1
                { 
                    rand 
= new Random(i * temp * ((int)DateTime.Now.Ticks)); 
                } 
                
int t = rand.Next(61); 
                
if (temp == t) 
                { 
                    
return CreateRandomCode(codeCount); 
                } 
                temp 
= t; 
                randomCode 
+= allCharArray[t]; 
            } 
            
return randomCode;
        }


  3、汉字验证码的实现,代码如下: 

        /**/
        
/* 
    此函数在汉字编码范围内随机创建含两个元素的十六进制字节数组,每个字节数组代表一个汉字,并将 
    四个字节数组存储在object数组中。 
    参数:strlength,代表需要产生的汉字个数 
    
*/
        
public static object[] CreateRegionCode(int strlength)
        {
            
//定义一个字符串数组储存汉字编码的组成元素 
            string[] rBase = new String[16] { "0""1""2""3""4""5""6""7""8""9""a""b""c""d""e""f" };
            Random rnd 
= new Random();
            
//定义一个object数组用来 
            object[] bytes = new object[strlength];

            
/**/
            
/*每循环一次产生一个含两个元素的十六进制字节数组,并将其放入bject数组中 
         每个汉字有四个区位码组成 
         区位码第1位和区位码第2位作为字节数组第一个元素 
         区位码第3位和区位码第4位作为字节数组第二个元素 
        
*/
            
for (int i = 0; i < strlength; i++)
            {
                
//区位码第1位 
                int r1 = rnd.Next(1114);
                
string str_r1 = rBase[r1].Trim();

                
//区位码第2位 
                rnd = new Random(r1 * unchecked((int)DateTime.Now.Ticks) + i);//更换随机数发生器的种子避免产生重复值 
                int r2;
                
if (r1 == 13)
                {
                    r2 
= rnd.Next(07);
                }
                
else
                {
                    r2 
= rnd.Next(016);
                }
                
string str_r2 = rBase[r2].Trim();

                
//区位码第3位 
                rnd = new Random(r2 * unchecked((int)DateTime.Now.Ticks) + i);
                
int r3 = rnd.Next(1016);
                
string str_r3 = rBase[r3].Trim();

                
//区位码第4位 
                rnd = new Random(r3 * unchecked((int)DateTime.Now.Ticks) + i);
                
int r4;
                
if (r3 == 10)
                {
                    r4 
= rnd.Next(116);
                }
                
else if (r3 == 15)
                {
                    r4 
= rnd.Next(015);
                }
                
else
                {
                    r4 
= rnd.Next(016);
                }
                
string str_r4 = rBase[r4].Trim();

                
//定义两个字节变量存储产生的随机汉字区位码 
                byte byte1 = Convert.ToByte(str_r1 + str_r2, 16);
                
byte byte2 = Convert.ToByte(str_r3 + str_r4, 16);
                
//将两个字节变量存储在字节数组中 
                byte[] str_r = new byte[] { byte1, byte2 };

                
//将产生的一个汉字的字节数组放入object数组中 
                bytes.SetValue(str_r, i);
            }
            
return bytes;
        }
  三、具体实例 
  (实例1) 
前台代码display.aspx

后台代码display.cs

后台代码png.cs

  (实例2):20101018续加
调用页面前台代码
        <script language="Javascript">
        
function Regist()
        {
            
var url = "";
            url 
= "/GZPI/Service/Registry/ViewProtocol.aspx";
            window.open(url);    
            
return false;
        }
        
function LoginClick()
        {
            
if(document.Login.UserName.value == "")
            {
                alert(
"用户名不能为空!");
                
return false;
            }
            document.Login.submit();
            document.Login.Password.value 
= "";
            
return false;
        }
        
        
function f_refreshtype()
        {    
            
var Image1 = document.getElementById("IMGCheckCode");
              
if (Image1 != null
               {
                   Image1.src 
= Image1.src + "?";
             }
        }        
        
</script>
                        
<TABLE cellSpacing="0" cellPadding="5" width="100%" border="0">
                            
<TR>
                                
<TD class="fontblack" align="right" width="30%">用 户 名:</TD>
                                
<TD vAlign="bottom" align="left" width="62%"><input id="Text1" style="BORDER-RIGHT: #43a7e2 1px solid; BORDER-TOP: #43a7e2 1px solid; BACKGROUND: #fcfcfc; BORDER-LEFT: #43a7e2 1px solid; BORDER-BOTTOM: #43a7e2 1px solid"
                                        size
="13" name="UserName" width="100px">
                                
</TD>
                            
</TR>
                            
<TR>
                                
<TD class="fontblack" align="right" height="23">密 &nbsp;&nbsp;&nbsp;码:</TD>
                                
<TD vAlign="bottom" align="left" height="23"><input id="Password1" style="BORDER-RIGHT: #43a7e2 1px solid; BORDER-TOP: #43a7e2 1px solid; BACKGROUND: #fcfcfc; BORDER-LEFT: #43a7e2 1px solid; BORDER-BOTTOM: #43a7e2 1px solid"
                                        type
="password" size="13" name="Password" width="100px">
                                
</TD>
                            
</TR>
                            
<TR>
                                
<TD class="fontblack" align="right" height="23">&nbsp;验 码:</TD>
                                
<TD valign="top" align="left" height="23"><FONT face="宋体"><INPUT id="CheckCode" style="BORDER-RIGHT: #43a7e2 1px solid; BORDER-TOP: #43a7e2 1px solid; BACKGROUND: #fcfcfc; BORDER-LEFT: #43a7e2 1px solid; BORDER-BOTTOM: #43a7e2 1px solid"
                                            width
="100px" size="13" name="CheckCode">&nbsp;</FONT><style="CURSOR: hand" onclick="f_refreshtype()" title="看不清楚?点击获取新的校验码!" border="0"><IMG id="IMGCheckCode" src="../GenerateCheckCode.aspx"></a>
                                
</TD>
                            
</TR>
                            
<TR vAlign="bottom" align="center">
                                
<TD class="dlbuttom" colSpan="2" height="23"><input id="Image1" style="CURSOR: hand" onclick="return LoginClick();" tabIndex="3" type="image"
                                        height
="17" width="55" src="images/login.gif" border="0" name="OkButton">&nbsp;&nbsp;&nbsp;
                                    
<input type="image" onClick="return Regist();" border='0' src='images/zuce.gif' width='55'
                                        
height='17' ID="Image2" NAME="Image2">
                                
</TD>
                            
</TR>
                        
</TABLE>

 


调用页面后台代码
    private void OK_Click(object sender, System.EventArgs e)
        {
            if (!CheckCodeSame(CheckCode.Text.Trim()))
            {                    
                System.Web.HttpContext.Current.Response.Write("
<Script Language='JavaScript'>window.alert('校验码错误!请重新输入!');window.close();</script>");
                return;
            }        
            int userType = 1;
            try
            {
                userType = int.Parse(UserType.Text);
            }
            catch
            {
            }

            GatewayManager gateway = new GatewayManager(corpCode.Text,collegeCode.Text,chargeCode.Text,userName.Text,password.Text,userType);
            gateway.Login(this);
        }

        /// 
<summary>
        /// 判断输入的校验码是否正确
        /// 
</summary>
        /// 
<param name="checkCode"></param>
        /// 
<returns></returns>
        public static bool CheckCodeSame(string checkCode)
        {
            bool bSame = false; ;

            if (HttpContext.Current.Session["CheckCode"] != null)
            {
                if (checkCode.ToUpper() == HttpContext.Current.Session["CheckCode"].ToString().ToUpper())
                {
                    bSame = true;
                }
            }
            return bSame;
        }

 

  
生成验证码前台文件
<HTML>
    
<HEAD>
        
<title>GenerateCheckCode</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>
        
<form id="form1" runat="server">
            
<div><FONT face="宋体"></FONT>
            
</div>
        
</form>
    
</body>
</HTML>

 


生成验证码后台文件
using System;
using System.Collections;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.Drawing.Drawing2D;


namespace GZPI.Gateway
{
    
/// <summary>
    
/// GenerateCheckCode 的摘要说明。
    
/// </summary>
    public class GenerateCheckCode : System.Web.UI.Page
    {
        
private void Page_Load(object sender, System.EventArgs e)
        {
            
// 在此处放置用户代码以初始化页面
            this.CreateCheckCodeImage(GenerateCheckCodes(4));
        }

        
#region Web 窗体设计器生成的代码
        
override protected void OnInit(EventArgs e)
        {
            
//
            
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
            
//
            InitializeComponent();
            
base.OnInit(e);
        }
        
        
/// <summary>
        
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
        
/// 此方法的内容。
        
/// </summary>
        private void InitializeComponent()
        {    
            
this.Load += new System.EventHandler(this.Page_Load);
        }
        
#endregion

        
private string GenerateCheckCodes(int iCount)
        {
            
int number;
            
string checkCode = String.Empty;
            
int iSeed = DateTime.Now.Millisecond;
            System.Random random 
= new Random(iSeed);
            
for (int i = 0; i < iCount; i++)
            {
                number 
= random.Next(10);
                checkCode 
+= number.ToString();
            }

            Session[
"CheckCode"= checkCode;
            
return checkCode;
        }



        
private void CreateCheckCodeImage(string checkCode)
        {
            
if (checkCode == null || checkCode.Trim() == String.Empty)
                
return;
            
int iWordWidth = 15;
            
int iImageWidth = checkCode.Length * iWordWidth;
            Bitmap image 
= new Bitmap(iImageWidth, 20);
            Graphics g 
= Graphics.FromImage(image);
            
try
            {
                
//生成随机生成器 
                Random random = new Random();
                
//清空图片背景色 
                g.Clear(Color.White);

                
//画图片的背景噪音点
                for (int i = 0; i < 20; 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);
                }

                
//画图片的背景噪音线 
                for (int i = 0; i < 2; i++)
                {
                    
int x1 = 0;
                    
int x2 = image.Width;
                    
int y1 = random.Next(image.Height);
                    
int y2 = random.Next(image.Height);
                    
if (i == 0)
                    {
                        g.DrawLine(
new Pen(Color.Gray, 2), x1, y1, x2, y2);
                    }
            
                }


                
for (int i = 0; i < checkCode.Length; i++)
                {

                    
string Code = checkCode[i].ToString();
                    
int xLeft = iWordWidth * (i);
                    random 
= new Random(xLeft);
                    
int iSeed = DateTime.Now.Millisecond;
                    
int iValue = random.Next(iSeed) % 4;
                    
if (iValue == 0)
                    {
                        Font font 
= new Font("Arial"13, (FontStyle.Bold | System.Drawing.FontStyle.Italic));
                        Rectangle rc 
= new Rectangle(xLeft, 0, iWordWidth, image.Height);
                        LinearGradientBrush brush 
= new LinearGradientBrush(rc, Color.Blue, Color.Red, 1.5ftrue);
                        g.DrawString(Code, font, brush, xLeft, 
2);
                    }
                    
else if (iValue == 1)
                    {
                        Font font 
= new System.Drawing.Font("楷体"13, (FontStyle.Bold));
                        Rectangle rc 
= new Rectangle(xLeft, 0, iWordWidth, image.Height);
                        LinearGradientBrush brush 
= new LinearGradientBrush(rc, Color.Blue, Color.DarkRed, 1.3ftrue);
                        g.DrawString(Code, font, brush, xLeft, 
2);
                    }
                    
else if (iValue == 2)
                    {
                        Font font 
= new System.Drawing.Font("宋体"13, (System.Drawing.FontStyle.Bold));
                        Rectangle rc 
= new Rectangle(xLeft, 0, iWordWidth, image.Height);
                        LinearGradientBrush brush 
= new LinearGradientBrush(rc, Color.Green, Color.Blue, 1.2ftrue);
                        g.DrawString(Code, font, brush, xLeft, 
2);
                    }
                    
else if (iValue == 3)
                    {
                        Font font 
= new System.Drawing.Font("黑体"13, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Bold));
                        Rectangle rc 
= new Rectangle(xLeft, 0, iWordWidth, image.Height);
                        LinearGradientBrush brush 
= new LinearGradientBrush(rc, Color.Blue, Color.Green, 1.8ftrue);
                        g.DrawString(Code, font, brush, xLeft, 
2);
                    }
                }
                
//////画图片的前景噪音点 
                //for (int i = 0; i < 8; i++)
                
//{
                
//    int x = random.Next(image.Width);
                
//    int y = random.Next(image.Height);
                
//    image.SetPixel(x, y, Color.FromArgb(random.Next()));
                
//}
                
//画图片的边框线 
                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.BinaryWrite(ms.ToArray());
            }
            
finally
            {
                g.Dispose();
                image.Dispose();
            }
        }
    }
}

 

  四、效果图展示
  
验证码数字

  验证码数字+字母

  验证码汉字