首先我们要创建一个图片服务页面,专门用于提供包含验证码文本的图片,为此我们建立一个 checkimage.aspx 的页面。其HTML代码很简单,只有一行,不输出任何内容。在其Page_Load方法中就有创建验证码图片的过程。

 

// 创建一个包含随机内容的验证码文本

System.Random rand = new Random();

int len = rand.Next(4 , 6 );

char[] chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();

System.Text.StringBuilder myStr = new System.Text.StringBuilder();

for( int iCount = 0 ; iCount < len ; iCount ++ )

{

myStr.Append( chars[ rand.Next( chars.Length )]);

}

string text = myStr.ToString();

// 保存验证码到 session 中以便其他模块使用

this.Session["checkcode"] = text ;

Size ImageSize = Size.Empty ;

Font myFont = new Font("MS Sans Serif" , 20 );

// 计算验证码图片大小

using( Bitmap bmp = new Bitmap( 10 , 10 ))

{

using( Graphics g = Graphics.FromImage( bmp ))

{

SizeF size = g.MeasureString( text , myFont , 10000 );

ImageSize.Width = ( int ) size.Width + 8 ;

ImageSize.Height = ( int ) size.Height + 8 ;

}

}

// 创建验证码图片

using( Bitmap bmp = new Bitmap( ImageSize.Width , ImageSize.Height ))

{

// 绘制验证码文本

using( Graphics g = Graphics.FromImage( bmp ))

{

g.Clear( Color.White );

using( StringFormat f = new StringFormat())

{

f.Alignment = StringAlignment.Near ;

f.LineAlignment = StringAlignment.Center ;

f.FormatFlags = StringFormatFlags.NoWrap ;

g.DrawString( text , myFont , Brushes.Black ,

new RectangleF( 0 , 0 , ImageSize.Width , ImageSize.Height ),

f );

}

}

// 制造噪声 杂点面积占图片面积的 30%

 

int num = ImageSize.Width * ImageSize.Height * 30 / 100 ;

for( int iCount = 0 ; iCount < num ; iCount ++ )

{

// 在随机的位置使用随机的颜色设置图片的像素

int x = rand.Next( ImageSize.Width );

int y = rand.Next( ImageSize.Height );

int r = rand.Next( 255 );

int g = rand.Next( 255 );

int b = rand.Next( 255 );

Color c = Color.FromArgb( r , g , b );

bmp.SetPixel( x , y , c );

}//for

// 输出图片

System.IO.MemoryStream ms = new System.IO.MemoryStream();

bmp.Save( ms , System.Drawing.Imaging.ImageFormat.Png );

this.Response.ContentType = "image/png";

ms.WriteTo( this.Response.OutputStream );

ms.Close();

}

myFont.Dispose();

首先我们使用.NET框架中随机数生成器 Random类型来生成一个不定长的包含随机数字和英文字符的文本,这就是验证码原始文本,我们将其保存在session中供以后使用。

然后我们创建一个临时图片,并据此创建一个临时的图象绘制对象,然后调用Graphics的MeasureString函数获得这个字符串的显示大小。据此我们就可以计算出验证码图片的大小。

然后我们创建一个位图对象,在此基础上创建一个图形绘制对象,然后调用图形绘制对象的DrawString函数将验证码文本绘制在这个位图上。

绘制验证码后我们在图片上随机的制造杂点来混淆图片内容。这些杂点的面积占图片面积的30%,而且其位置和颜色都是随机的。这些杂点能严重的干扰程序辨认验证码文本。但人脑在辨认文本时能比较轻松的排除这些干扰。

图片生成后页面就使用PNG格式将图片文档发送到客户端。

checkimage.aspx还提供了一个静态函数来检测验证码。

/// 检查指定的文本是否匹配验证码

/// 要判断的文本是否匹配

public static bool CheckCode( string text )

{

string txt = System.Web.HttpContext.Current.Session["checkcode"] as string ;

return text == txt ;

}

代码很简单。就是看看参数传进的文本是否等于 session 中保存的验证码文本。其他的页面程序调用这个函数就可以判断验证码的正确性。

login.aspx

验证码图片服务页面完成后,我们就可以利用这个页面来实现验证码技术。我们建立一个模拟系统登录的页面。

在少数情况下,程序生成的验证码图片难以辨认,则需要重新提供新的验证码图片,此时我们在登录页面中可以双击这个图片来更新验证码图片。显示验证码图片的HTML代码片断为

title='看不清楚,双击图片换一张。'

ondblclick="this.src = 'checkimage.aspx?flag=' + Math.random() "

border="1">