验证码实现
上午老大安排的各种恶心的一个asp报表做完了,里面的流程的复杂导致sql语言冗长的很,优化了一段之后还是要运行1分半左右才能查询出来..不过,总算是完成了
,
下午看看看tony给我的一些小模块,里面的一个验证码模块需要完善,当然,以前对验证码这东西也挺感兴趣的,今天动手终于把他实现了...当然,网上的东西也借鉴了不少.看看代码吧:
首先是一个产生图片的一个类,网上一大把一大把的,都大同小异,本着拿来主义的精神,我也不能免俗,copy过来了,当然进行了小修改咯.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Web;
/// <summary>
/// 产生随即图片
/// </summary>
public sealed class RandImage
{
private const string RandCharString = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private int width;
private int height;
private int length;
/// <summary>
/// 默认构造函数,生成的图片宽度为48×20,随即字符串字符个数
/// </summary>
public RandImage():this(48,20,4)
{
}
/// <summary>
/// 指定生成图片的宽和高,默认生成图片的字符串长度为4个字符
/// </summary>
/// <param name="width"></param>
/// <param name="height"></param>
public RandImage(int width, int height):this(width,height,4)
{
}
/// <summary>
/// 指定生成图片的宽和高以及生成图片的字符串字符个数
/// </summary>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="length"></param>
public RandImage(int width, int height, int length)
{
this.width = width;
this.height = height;
this.length = length;
}
/// <summary>
/// 以前的改方法是产生随机字符与产生新图片放在一起,为了在登录页面对验证验进行证码,将产生随机字符的方法与产生图片的方法分开来,以便在产生一个随机字符便存在Session中
/// </summary>
public string GenerateRandomCode()
{
StringBuilder sb = new StringBuilder();
Random random = new Random();
do
{
//使用DateTime.Now.Millisecond作为生成随机数的参数,增加随机性
sb.Append(RandCharString.Substring(random.Next(DateTime.Now.Millisecond) % RandCharString.Length, 1));
}
while (sb.Length< 4);
return sb.ToString();
}
/// <summary>
/// 以默认的大小和默认的字符个数产生图片
/// </summary>
/// <returns></returns>
public Image GetImage(string randString)
{
Bitmap image = new Bitmap(width, height);
Graphics g = Graphics.FromImage(image);
randString = GenerateRandomCode();
g.Clear(Color.White);
Random random=new Random();
float emSize=(float)width/randString.Length;
Font font = new Font("Arial", emSize, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic));
Pen pen = new Pen(Color.Silver);
#region 画图片的背景噪音线
int x1,y1,x2,y2;
for (int i = 0; i < 25; i++)
{
x1 = random.Next(image.Width);
y1 = random.Next(image.Height);
x2 = random.Next(image.Width);
y2 = random.Next(image.Height);
g.DrawLine(pen, x1, y1, x2, y2);
}
#endregion
#region 画图片的前景噪音点
for (int i = 0; i < 100; i++)
{
x1 = random.Next(image.Width);
y1 = random.Next(image.Height);
image.SetPixel(x1, y1, Color.FromArgb(random.Next(Int32.MaxValue)));
}
#endregion
g.DrawString(randString, font, Brushes.Green, 2, 2);
g.Dispose();
return image;
}
}
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Web;
/// <summary>
/// 产生随即图片
/// </summary>
public sealed class RandImage
{
private const string RandCharString = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private int width;
private int height;
private int length;
/// <summary>
/// 默认构造函数,生成的图片宽度为48×20,随即字符串字符个数
/// </summary>
public RandImage():this(48,20,4)
{
}
/// <summary>
/// 指定生成图片的宽和高,默认生成图片的字符串长度为4个字符
/// </summary>
/// <param name="width"></param>
/// <param name="height"></param>
public RandImage(int width, int height):this(width,height,4)
{
}
/// <summary>
/// 指定生成图片的宽和高以及生成图片的字符串字符个数
/// </summary>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="length"></param>
public RandImage(int width, int height, int length)
{
this.width = width;
this.height = height;
this.length = length;
}
/// <summary>
/// 以前的改方法是产生随机字符与产生新图片放在一起,为了在登录页面对验证验进行证码,将产生随机字符的方法与产生图片的方法分开来,以便在产生一个随机字符便存在Session中
/// </summary>
public string GenerateRandomCode()
{
StringBuilder sb = new StringBuilder();
Random random = new Random();
do
{
//使用DateTime.Now.Millisecond作为生成随机数的参数,增加随机性
sb.Append(RandCharString.Substring(random.Next(DateTime.Now.Millisecond) % RandCharString.Length, 1));
}
while (sb.Length< 4);
return sb.ToString();
}
/// <summary>
/// 以默认的大小和默认的字符个数产生图片
/// </summary>
/// <returns></returns>
public Image GetImage(string randString)
{
Bitmap image = new Bitmap(width, height);
Graphics g = Graphics.FromImage(image);
randString = GenerateRandomCode();
g.Clear(Color.White);
Random random=new Random();
float emSize=(float)width/randString.Length;
Font font = new Font("Arial", emSize, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic));
Pen pen = new Pen(Color.Silver);
#region 画图片的背景噪音线
int x1,y1,x2,y2;
for (int i = 0; i < 25; i++)
{
x1 = random.Next(image.Width);
y1 = random.Next(image.Height);
x2 = random.Next(image.Width);
y2 = random.Next(image.Height);
g.DrawLine(pen, x1, y1, x2, y2);
}
#endregion
#region 画图片的前景噪音点
for (int i = 0; i < 100; i++)
{
x1 = random.Next(image.Width);
y1 = random.Next(image.Height);
image.SetPixel(x1, y1, Color.FromArgb(random.Next(Int32.MaxValue)));
}
#endregion
g.DrawString(randString, font, Brushes.Green, 2, 2);
g.Dispose();
return image;
}
}
其实,这个类主要是摘自与csdn周公的一篇验证码的文章,只是他将产生随机字符的与产生图片的方法写在一块了,因为他最后没有在登录界面对输入验证码的正确性进行验证,所以他就没有将生成的随机字符串进行保存.而对于我来说,我需要将字符串单独保存存在一个Session中,以便在登录界面验证其正确性性,所以我将生成随机字符与生成图片分别写成了2个方法.
接下来是调用该类的一个页面,用来产生图片,改页面没有任何的前台内容,只有后台cs.
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.IO;
using System.Drawing;
using System.Drawing.Imaging;
public partial class CheckImage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
RandImage randImage=new RandImage();
string GenerateRndCode = randImage.GenerateRandomCode();
Session["RandomCode"] = GenerateRndCode;//将产生的随机数存在Session中,以便在登录时用于与用户所填写的进行比较
System.Drawing.Image image = randImage.GetImage(GenerateRndCode);
System.IO.MemoryStream memoryStream = new MemoryStream();
image.Save(memoryStream, ImageFormat.Jpeg);
Response.ClearContent();
Response.ContentType = "image/gif";
Response.BinaryWrite(memoryStream.ToArray());
image.Dispose();
Response.End();
}
}
}
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.IO;
using System.Drawing;
using System.Drawing.Imaging;
public partial class CheckImage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
RandImage randImage=new RandImage();
string GenerateRndCode = randImage.GenerateRandomCode();
Session["RandomCode"] = GenerateRndCode;//将产生的随机数存在Session中,以便在登录时用于与用户所填写的进行比较
System.Drawing.Image image = randImage.GetImage(GenerateRndCode);
System.IO.MemoryStream memoryStream = new MemoryStream();
image.Save(memoryStream, ImageFormat.Jpeg);
Response.ClearContent();
Response.ContentType = "image/gif";
Response.BinaryWrite(memoryStream.ToArray());
image.Dispose();
Response.End();
}
}
}
至此,图片及随机字符串已经在手里了,接下来的事是调用了.调用其实很简单,在输入验证码的的textbox后面添加以下东西就好:
<img id ="Picflush" alt="点击刷新验证码" src="CheckImage.aspx" onclick="getimgcode('Picflush')" />
src即为产生图片的aspx页面,onclick事件是为了响应一个javascript事件,该事件发生后能刷新验证码,以防止有些验证码模糊无法填写的情况.
javascript事件为:
<script type="text/javascript">
function getimgcode(ID) {
document.getElementById(ID).src = "CheckImage.aspx?t=" + (new Date()).getTime(); //随机数保证验证码不缓存
}
</script>
function getimgcode(ID) {
document.getElementById(ID).src = "CheckImage.aspx?t=" + (new Date()).getTime(); //随机数保证验证码不缓存
}
</script>
最后是后台的验证:
if (string.Compare(Session["RandomCode"].ToString(), this.CheckCode.Text, true) != 0)
{
this.CheckCode.Focus();
this.CheckCode.Text = string.Empty;
MessageBox.Show(this, "验证码错误,请重新填写");
return;
}
{
this.CheckCode.Focus();
this.CheckCode.Text = string.Empty;
MessageBox.Show(this, "验证码错误,请重新填写");
return;
}
至此,验证码基本完成了,最后的效果:

就是这酱紫.
浙公网安备 33010602011771号