验证码的三种做法[纯数字][纯汉字][字母/数字/汉字混合]

来源:互联网 发布:java对象内存分配 编辑:程序博客网 时间:2024/04/29 16:45

网上有很多关于验证码做法的资料,但是真正做得完整的却非常少,所以昨天晚上参考了作者:CSDN 上kwklover 的 在ASP.NET下实现数字和字符相混合的验证码 (混合,完整,遗憾的是vb.net,说到这里我想我得感谢stone(QQ9337874),因为我在把VB译成C#的过程中几番出错,最终这段翻译由他完成)!!

随机汉字参考了
http://navicy.cnblogs.com/archive/2005/05/08/150756.html 这篇文章的,

而最终的纯数字以及GDI+绘图则是从□☆近三十☆(QQ19302038)传给我的一个OA案例里面分离出来的!

所以完整的说,这里面几乎都是别人做好了的,我只是整理出来了!

完整的下载地址是 
http://www.cnblogs.com/Files/thcjp/gdi.rar  

下面把代码的重点部分贴出来,如果看源文件有什么不明白可以问偶 QQ110535808

效果如图(我确实懒了点,按纽的名字都没有改,哈哈)
需要说明的是,因为提交对比后,页面是重新刷新了,所以文本框里面看见的和后面图片显示不一样,这个不需要太多说明吧!!

 混合模式刷新出现约界错误 已经被 stone(QQ9337874) 修正!!


下面是GDI+绘图的代码段,以及显示的调用等
using  System;
using
 System.Data;
using
 System.Configuration;
using
 System.Collections;
using
 System.Web;
using
 System.Web.Security;
using
 System.Web.UI;
using
 System.Web.UI.WebControls;
using
 System.Web.UI.WebControls.WebParts;
using
 System.Web.UI.HtmlControls;
using
 System.Drawing.Drawing2D;
using
 System.Drawing.Imaging;
using
 System.Drawing.Text;
using
 System.Drawing;
using
 System.Text; 

public  partial  class
 png : System.Web.UI.Page
{
    
private   readonly   string  ImagePath  =   " Validator.jpg "
;
    
private   static   string  gif  =   ""
;

    
protected   void  Page_Load( object
 sender, EventArgs e)
    
{

        
switch  (Request.QueryString[ " aa "
])
        
{
            
case   " 1 "
:
                gif 
=
 stxt();
                Session[
" gif " ] =
 stxt();
                
break
;
            
case   " 2 "
:
                gif 
=
 GetRandomint();
                 Session[
" gif " ] =
 GetRandomint();
                
break
;
            
case   " 3 "
:
                gif 
=  RndNum( 3
);
                 Session[
" gif " ] =  RndNum( 3
);
                
break
;
            
default
:
                gif 
=  RndNum( 3
);
                 Session[
" gif " ] =
 GetRandomint();
                
break
;
        }

        
        
/// 创建Bmp位图
        Bitmap bitMapImage  =   new
 System.Drawing.Bitmap(Server.MapPath(ImagePath));
        Graphics graphicImage 
=
 Graphics.FromImage(bitMapImage);

        
/// 设置画笔的输出模式
        graphicImage.SmoothingMode  =
 SmoothingMode.HighSpeed;
        
/// 添加文本字符串
        graphicImage.DrawString(gif,  new  Font( " Arial " 20 , FontStyle.Bold), SystemBrushes.WindowText,  new  Point( 0 0
));

        
/// 设置图像输出的格式
        Response.ContentType  =   " image/jpeg "
;

        
/// 保存数据流
        bitMapImage.Save(Response.OutputStream, ImageFormat.Jpeg);

        
/// 释放占用的资源
        graphicImage.Dispose();
        bitMapImage.Dispose();
    }

返回纯数字

     private  String GetRandomint()
    
{
        Random random 
=   new
 Random();
        
return  (random.Next( 100000 999999
).ToString());
    }


返回文字\数字\字母混合的

public   static  String RndNum( int  VcodeNum)
    
{
        String Vchar 
=   " 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,呵,哈,弹,簧,秤,嬉,戏 "
;
        String[] VcArray 
=  Vchar.Split( ' , '
);
        String VNum 
=   ""
;
        Random random 
=   new
 Random();
        
for  ( int  i  =   1 ; i  <=  VcodeNum; i ++
)
        
{
            
int  iNum  =   0
;
            
while  ((iNum  =  Convert.ToInt32(VcArray.Length  *  random.NextDouble()))  ==VcArray.Length  
)
            
{
                iNum 
=  Convert.ToInt32(VcArray.Length  *
 random.NextDouble());
            }

            VNum 
+=  VcArray[iNum];
            
//  VNum += VcArray[Convert.ToInt32(VcArray.Length*random.NextDouble())];

        }

        
return  VNum;
    }
 

返回汉字的
        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; 
 
            }

    
private   string  stxt()
    
{
        Encoding gb 
=  Encoding.GetEncoding( " gb2312 "
);

        
// 调用函数产生4个随机中文汉字编码 

         object [] bytes  =  CreateRegionCode( 3 );

        
// 根据汉字编码的字节数组解码出中文汉字 

         string  str1  =  gb.GetString(( byte [])Convert.ChangeType(bytes[ 0 ],  typeof ( byte [])));
        
string  str2  =  gb.GetString(( byte [])Convert.ChangeType(bytes[ 1 ],  typeof ( byte
[])));
        
string  str3  =  gb.GetString(( byte [])Convert.ChangeType(bytes[ 2 ],  typeof ( byte
[])));

        
string  txt  =  str1  +  str2  +
 str3;
        
return
 txt;
    }

我们调用页的代码如下

HTML代码
<% @ Page Language = " C# "  AutoEventWireup = " true "  CodeFile = " view.aspx.cs "  Inherits = " view "   %>

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >

< html  xmlns ="http://www.w3.org/1999/xhtml"   >
< head  runat ="server" >
    
< title > 无标题页 </ title >
</ head >
< body >
    
< form  id ="form1"  runat ="server" >
    
< div >
        
&nbsp; < asp:TextBox  ID ="TextBox1"  runat ="server" ></ asp:TextBox >
        
< asp:Image  ID ="Image1"  runat ="server"  ImageUrl ="png.aspx"   />< br  />
        
< br  />
        
&nbsp; < asp:Button  ID ="Button2"  runat ="server"  OnClick ="Button2_Click"  Text ="Button"   />
        
< asp:DropDownList  ID ="DropDownList1"  runat ="server"  AutoPostBack ="True"  OnSelectedIndexChanged ="DropDownList1_SelectedIndexChanged" >
            
< asp:ListItem  Value ="3" > 默认 </ asp:ListItem >
            
< asp:ListItem  Value ="1" > 文字 </ asp:ListItem >
            
< asp:ListItem  Value ="2" > 数字 </ asp:ListItem >
            
< asp:ListItem  Value ="3" > 混合 </ asp:ListItem >
        
</ asp:DropDownList ></ div >
    
</ form >
</ body >
</ html >

CS代码
     protected   void  DropDownList1_SelectedIndexChanged( object  sender, EventArgs e)
    
{
        
switch
 (DropDownList1.SelectedValue)
        
{
            
case   " 1 "
:
                Image1.ImageUrl 
=   " png.aspx?aa=1 "
;
                
break
;
            
case   " 2 "
:
                Image1.ImageUrl 
=   " png.aspx?aa=2 "
;
                
break
;
            
case   " 3 "
:
                Image1.ImageUrl 
=   " png.aspx?aa=3 "
;
                
break
;
        }

    }

    
protected   void  Button2_Click( object  sender, EventArgs e)
    
{
        
if  (TextBox1.Text  ==  Session[ " gif "
].ToString())
            Response.Write(
" OK,正确 "
);
        
else

            Response.Write(
" 验证码不符合 " );
 
原创粉丝点击