.net实现验证码功能

  一、验证码简介
  验证码功能一般是用于防止批量注册的,不少网站为了防止用户利用机器人自动注册、登录、灌水,都采用了验证码技术。所谓验证码,就是将一串随机产生的数字或字母或符号或文字,生成一幅图片, 图片里加上一些干扰象素(防止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( 11 14 );
                
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( 0 7 );
                }
                
else
                {
                    r2 
=  rnd.Next( 0 16 );
                }
                
string  str_r2  =  rBase[r2].Trim();

                
// 区位码第3位 
                rnd  =   new  Random(r2  *   unchecked (( int )DateTime.Now.Ticks)  +  i);
                
int  r3  =  rnd.Next( 10 16 );
                
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( 1 16 );
                }
                
else   if  (r3  ==   15 )
                {
                    r4 
=  rnd.Next( 0 15 );
                }
                
else
                {
                    r4 
=  rnd.Next( 0 16 );
                }
                
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.5f true );
                        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.3f true );
                        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.2f true );
                        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.8f true );
                        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),  0 0 , 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();
            }
        }
    }
}

 

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

  验证码数字+字母

  验证码汉字

.net实现验证码功能

你可能感兴趣的:(.net)