| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 10120 人关注过本帖, 16 人收藏
标题:最新发布,验证码控件,绝对原创
只看楼主 加入收藏
铲铲
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:34
帖 子:506
专家分:0
注 册:2006-5-2
结帖率:100%
收藏(16)
 问题点数:0 回复次数:37 
最新发布,验证码控件,绝对原创
这是我历时一个月逐渐完善的验证码控件。有如下特性:
1、基于流方式生成图片,突破文件系统局限,并且对每个访问网站的对话隔离,互不影响。
2、采用稳定性较好的ViewState,使用T-DES算法和MachineKey加密敏感数据。
3、可选数字、小写字母、大写字母、100个常用汉字任意搭配。
4、提供一个验证方法(返回布尔),验证方法还可设置是否区分大小写验证。
5、提供划线和打点方式的噪音生成,并可设置强度值。
6、图片背景、字符、噪音均可自行设置颜色。
7、可选生成字符字体(基于服务器已有字体)
8、兼容XHTML标准和完备样式。
9、配备IHttpHandler接口。
10、基本的设计时支持。(但在VS2008 .net3.5下没有成功:(~~)

验证码控件结构如下:
class VerificationCode 验证码控件主体。
enum VerificationCodeImageFormat 枚举验证码控件输出图片的格式。gif或jpg
enum VerificationCodeNoiseRenderMode 枚举验证码噪音渲染模式,是在字符底层渲染还是在字符上层渲染。
enum VerificationCodeNoiseType 枚举验证码渲染类型,点或直线。
class VCodeTransferFormatter 用于将验证码对象信息格式化传输的格式器
class VerificationCodeDesigner 对验证码控件提供设计时支持
class TDesEncrpytor 封装一个TDES加密解密器
class TDesDecryptException 捕捉加密解密异常,从Exception简单继承。

代码公布如下:

程序代码:
using System;
using System.Collections.Generic;
using  System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing.Design;
using System.Drawing;
using System.Collections;
using System.Web.Security;
using System.Drawing.Imaging;
using System.Reflection;
using System.Security.Cryptography;
using  System.Drawing.Text;

namespace BlogLan.Web.Controls
{
    /// <summary>
    /// 验证码控件。
    /// </summary>
    [DefaultProperty("CodeLength")]
    [ToolboxData("<{0}:VerificationCode runat=server></{0}:VerificationCode>")]
    [DesignerAttribute(typeof(Designer.VerificationCodeDesigner))]
    [Description("验证码控件。")]
    public class VerificationCode : WebControl, IHttpHandler
    {
        private Random rand;

        /// <summary>
        /// 表示数字字符集。
        /// </summary>
        public static char[] NumericCharset = new char[] { '2', '3', '4', '5', '6', '7' };
        /// <summary>
        /// 表示大写英文字母字符集。
        /// </summary>
        public static char[] UppercaseCharset = new char[] { 'A', 'B', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'Q', 'R', 'T', 'W', 'X', 'Y' };
        /// <summary>
        /// 表示小写英文字母字符集。
        /// </summary>
        public static char[] LowercaseCharset = new char[] { 'a', 'b', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'r', 't', 'u', 'w', 'x', 'y' };
        /// <summary>
        /// 表示100个最常用简体中文汉字字符集。
        /// </summary>
        public static char[] ChineseCharset = new char[]{'的','一','是','在','不','了','有','和','人','这',
                                                        '中','大','为','上','个','国','我','以','要','他',
                                                        '时','来','用','们','生','到','作','地','于','出',
                                                        '就','分','对','成','会','可','主','发','年','动',
                                                        '同','工','也','能','下','过','子','说','产','种',
                                                        '面','而','方','后','多','定','行','学','法','所',
                                                        '民','得','经','十','三','之','进','着','等','部',
                                                        '度','家','电','力','里','如','水','化','高','自',
                                                        '二','理','起','小','物','现','实','加','量','都',
                                                        '两','体','制','机','当','使','点','从','业','本'};

        /// <summary>
        /// 默认构造函数。
        /// </summary>
        public VerificationCode()
            : base(HtmlTextWriterTag.Img)
        {
            rand = new Random(unchecked((int)DateTime.Now.Ticks));
        }

        private byte[] GetMachineKey()
        {
            try
            {
                object machineKeyConfig = HttpContext.Current.GetSection("system.web/machineKey");
                Type machineKeyType = machineKeyConfig.GetType().Assembly.GetType("System.Web.Configuration.MachineKey");
                //得到System.Web.Configuration.MachineKey类型
                BindingFlags bf = BindingFlags.NonPublic | BindingFlags.Static;
                //设置绑定标志
                MethodInfo byteArrayToHexString = machineKeyType.GetMethod("ByteArrayToHexString", bf);

                SymmetricAlgorithm algorithm = (SymmetricAlgorithm)machineKeyType.GetField("s_oDes", bf).GetValue(machineKeyConfig);
                Byte[] decryptionKey = algorithm.Key;
                return decryptionKey;
            }
            catch
            {
                return new byte[]{77,236,150,65,103,91,220,81,
                                     49,37,48,208,73,85,150,250,
                                     131,25,228,234,2,155,26,167};
            }
        }

        /// <summary>
        /// 获取或设置生成的验证字符个数。
        /// </summary>
        [DefaultValue(4)]
        [Bindable(true)]
        [Description("获取或设置生成的验证字符个数。")]
        public int CodeLength
        {
            get
            {
                if (this.ViewState["CodeLength"] != null)
                {
                    return (int)this.ViewState["CodeLength"];
                }
                return 4;
            }
            set
            {
                this.ViewState["CodeLength"] = value;
            }
        }

        /// <summary>
        /// 获取或设置生成的缩略图的图片格式。
        /// </summary>
        [Bindable(false)]
        [DefaultValue(VerificationCodeImageFormat.Gif)]
        [Description("获取或设置生成的缩略图的图片格式。")]
        public VerificationCodeImageFormat ImageFormat
        {
            get
            {
                if (this.ViewState["ImageFormat"] != null)
                {
                    return (VerificationCodeImageFormat)this.ViewState["ImageFormat"];
                }
                return VerificationCodeImageFormat.Gif;
            }
            set
            {
                this.ViewState["ImageFormat"] = value;
            }
        }

        /// <summary>
        /// 获取或设置进行验证时是否区分大小写。
        /// </summary>
        [Bindable(false)]
        [DefaultValue(false)]
        [Description("获取或设置进行验证时是否区分大小写。")]
        public bool CaseSensitive
        {
            get
            {
                if (this.ViewState["CaseSensitive"] != null)
                {
                    return (bool)this.ViewState["CaseSensitive"];
                }
                return false;
            }
            set
            {
                this.ViewState["CaseSensitive"] = value;
            }
        }

        /// <summary>
        /// 获取或设置图片背景色。
        /// </summary>
        [DefaultValue(typeof(Color), "Black"), Description("获取或设置图片背景色。")]
        public override Color BackColor
        {
            get
            {
                if (!base.BackColor.IsEmpty)
                    return base.BackColor;
                return Color.Black;
            }
            set
            {
                base.BackColor = value;
            }
        }

        /// <summary>
        /// 获取或设置前景颜色,通常就是图片上显示的文字颜色。
        /// </summary>
        [DefaultValue(typeof(Color), "White"), Description("获取或设置前景颜色,通常就是图片上显示的文字颜色。")]
        public override Color ForeColor
        {
            get
            {
                if (!base.ForeColor.IsEmpty)
                    return base.ForeColor;
                return Color.White;
            }
            set
            {
                base.ForeColor = value;
            }
        }

        /// <summary>
        /// 获取或设置Jpeg图片质量。数值在10-100之间。
        /// </summary>
        [DefaultValue(80), Description("获取或设置Jpeg图片质量。数值在10-100之间。")]
        public int JpegQualityPercentage
        {
            get
            {
                if (this.ViewState["JpegQualityPercentage"] != null)
                {
                    int jqp = (int)this.ViewState["JpegQualityPercentage"];
                    if (jqp > 100)
                        return 100;
                    if (jqp < 10)
                        return 10;
                    return jqp;
                }
                return 80;
            }
            set
            {
                this.ViewState["JpegQualityPercentage"] = value;
            }
        }

        /// <summary>
        /// 获取或设置图像噪音干扰的颜色。
        /// </summary>
        [DefaultValue(typeof(Color), "White"), Description("获取或设置图像噪音干扰的颜色。")]
        public Color NoiseColor
        {
            get
            {
                if (this.ViewState["NoiseColor"] != null)
                {
                    return (Color)this.ViewState["NoiseColor"];
                }
                return Color.White;
            }
            set
            {
                this.ViewState["NoiseColor"] = value;
            }
        }

        /// <summary>
        /// 获取或设置噪音渲染位置。
        /// </summary>
        [DefaultValue(VerificationCodeNoiseRenderMode.Back), Description("获取或设置噪音渲染位置。")]
        public VerificationCodeNoiseRenderMode NoiseRenderMode
        {
            get
            {
                if (this.ViewState["NoiseRenderMode"] != null)
                {
                    return (VerificationCodeNoiseRenderMode)this.ViewState["NoiseRenderMode"];
                }
                return VerificationCodeNoiseRenderMode.Back;
            }
            set
            {
                this.ViewState["NoiseRenderMode"] = value;
            }
        }

        /// <summary>
        /// 获取或设置噪音类型。
        /// </summary>
        [DefaultValue(VerificationCodeNoiseType.Spot), Description("获取或设置噪音类型。")]
        public VerificationCodeNoiseType NoiseType
        {
            get
            {
                if (this.ViewState["NoiseType"] != null)
                {
                    return (VerificationCodeNoiseType)this.ViewState["NoiseType"];
                }
                return VerificationCodeNoiseType.Spot;
            }
            set
            {
                this.ViewState["NoiseType"] = value;
            }
        }

        /// <summary>
        /// 获取或设置噪音渲染强度。值范围是0-100,如果设置为0,则不进行噪音渲染。
        /// </summary>
        [DefaultValue(0), Description("获取或设置噪音渲染强度。值范围是0-100,如果设置为0,则不进行噪音渲染。")]
        public int NoiseRendingIntensity
        {
            get
            {
                if (this.ViewState["NoiseRendingIntensity"] != null)
                {
                    int nri = (int)this.ViewState["NoiseRendingIntensity"];
                    if (nri < 0)
                        return 0;
                    if (nri > 100)
                        return 100;

                    return nri;
                }
                return 0;
            }
            set
            {
                this.ViewState["NoiseRendingIntensity"] = value;
            }
        }

        /// <summary>
        /// 获取设计时生成的HTML语句。
        /// </summary>
        /// <param name="writer">要写入HTML语句的HtmlTextWriter。</param>
        protected internal void GetDesignTimeCode(HtmlTextWriter writer)
        {
            string ErrorMsg = string.Empty;
            try
            {
                char[] charset = this.CreateUsedCharset();
                string OCode = this.GenerateCodeValue(charset, this.CodeLength);
                this.EncryptCodeValue(OCode);
            }
            catch (Exception ex)
            {
                this.EncryptCodeValue(string.Empty);
                ErrorMsg = ex.Message;
                //return;
            }

            Bitmap bmp = this.GetVerificationCodeImage();
            string tempUrl = Path.GetTempPath();
            if (tempUrl == string.Empty)
                tempUrl = "C:\\";
            tempUrl += Guid.NewGuid().ToString();

            if (this.ImageFormat == VerificationCodeImageFormat.Gif)
            {
                tempUrl += ".gif";
                bmp.Save(tempUrl, System.Drawing.Imaging.ImageFormat.Gif);
            }
            else if (this.ImageFormat == VerificationCodeImageFormat.Jpeg)
            {
                tempUrl += ".jpg";
                bmp.Save(tempUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
            }

            
            this.AddVCodeAttributes(writer, tempUrl);
            writer.RenderBeginTag(HtmlTextWriterTag.Img);
            writer.RenderEndTag();
            writer.Write(ErrorMsg);
            //writer.Write("<img src=\"" + tempUrl + "\" />");
        }

        /// <summary>
        /// 添加VerificationCode属性到HTML标记中。
        /// </summary>
        /// <param name="writer">要写入属性的HtmlTextWriter。</param>
        /// <param name="ImageUrl">图片的Url路径。</param>
        protected internal void AddVCodeAttributes(HtmlTextWriter writer, string ImageUrl)
        {
            base.AddAttributesToRender(writer);
            string imageUrl = ImageUrl;
            if (!this.UrlResolved)
            {
                imageUrl = base.ResolveClientUrl(imageUrl);
            }

            writer.AddAttribute(HtmlTextWriterAttribute.Src, imageUrl);

            imageUrl = this.DescriptionUrl;
            if (imageUrl.Length != 0)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Longdesc, base.ResolveClientUrl(imageUrl));
            }
            imageUrl = this.AlternateText;
            if ((imageUrl.Length > 0) || this.GenerateEmptyAlternateText)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Alt, imageUrl);
            }
            switch (this.ImageAlign)
            {
                case ImageAlign.Left:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "left");
                    break;

                case ImageAlign.Right:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "right");
                    break;

                case ImageAlign.Baseline:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "baseline");
                    break;

                case ImageAlign.Top:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "top");
                    break;

                case ImageAlign.Middle:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "middle");
                    break;

                case ImageAlign.Bottom:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "bottom");
                    break;

                case ImageAlign.AbsBottom:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "absbottom");
                    break;

                case ImageAlign.AbsMiddle:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "absmiddle");
                    break;

                case ImageAlign.NotSet:
                    break;

                default:
                    writer.AddAttribute(HtmlTextWriterAttribute.Align, "texttop");
                    break;
            }

            if (this.BorderWidth.IsEmpty)
            {
                writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "0px");
            }
        }

        /// <summary>
        /// 将需要为控件呈现的 HTML 属性和样式添加到指定的 HtmlTextWriter 对象。这通常由系统调用,可以在派生类中重写。
        /// </summary>
        /// <param name="writer">表示要在客户端呈现 HTML 内容的输出流。</param>
        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            if (string.IsNullOrEmpty(this.Page.Request["vrfc"]))
            {
                VCodeTransferFormatter formatter = new VCodeTransferFormatter();
                string querystr = formatter.SerializeFromVCodeControl(this);

                
                string imageUrl = this.Page.Request.Url.AbsolutePath + "?vrfc=" + querystr;
                this.AddVCodeAttributes(writer, imageUrl);
                
            }
        }

        /// <summary>
        /// 将控件的内容呈现到指定的编写器中。此方法主要由控件开发人员使用。
        /// </summary>
        /// <param name="writer">表示要在客户端呈现 HTML 内容的输出流。</param>
        protected override void RenderContents(HtmlTextWriter writer)
        {
        }

        private bool urlResolved;

        internal bool UrlResolved
        {
            get
            {
                return this.urlResolved;
            }
            set
            {
                this.urlResolved = value;
            }
        }

        /// <summary>
        /// 如无法显示图片时显示的替代文本。
        /// </summary>
        [DefaultValue("Virtual Verification"), Bindable(true), Localizable(true), Description("如无法显示图片时显示的替代文本。")]
        public virtual string AlternateText
        {
            get
            {
                if (this.ViewState["AlternateText"] != null)
                {
                    return (string)this.ViewState["AlternateText"];
                }
                return "Virtual Verification";
            }
            set
            {
                this.ViewState["AlternateText"] = value;
            }
        }

        /// <summary>
        /// 获取或设置一个值,该值指示控件是否生成空字符串值的替换文字属性。
        /// </summary>
        [DefaultValue(true), Description("获取或设置一个值,该值指示控件是否生成空字符串值的替换文字属性。")]
        public virtual bool GenerateEmptyAlternateText
        {
            get
            {
                if (this.ViewState["GenerateEmptyAlternateText"] != null)
                {
                    return (bool)this.ViewState["GenerateEmptyAlternateText"];
                }
                return true;
            }
            set
            {
                this.ViewState["GenerateEmptyAlternateText"] = value;
            }
        }

        /// <summary>
        /// 获取或设置图像详细说明的位置。
        /// </summary>
        [Editor("System.Web.UI.Design.UrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), UrlProperty, DefaultValue(""), Description("获取或设置图像详细说明的位置。")]
        public virtual string DescriptionUrl
        {
            get
            {
                string str = (string)this.ViewState["DescriptionUrl"];
                if (str != null)
                {
                    return str;
                }
                return string.Empty;
            }
            set
            {
                this.ViewState["DescriptionUrl"] = value;
            }
        }

        /// <summary>
        /// 获取或设置控件相对于网页上其他元素的对齐方式。
        /// </summary>
        [DefaultValue(ImageAlign.NotSet), Description("获取或设置控件相对于网页上其他元素的对齐方式。")]
        public virtual ImageAlign ImageAlign
        {
            get
            {
                object obj2 = this.ViewState["ImageAlign"];
                if (obj2 != null)
                {
                    return (ImageAlign)obj2;
                }
                return ImageAlign.NotSet;
            }
            set
            {
                if ((value < ImageAlign.NotSet) || (value > ImageAlign.TextTop))
                {
                    throw new ArgumentOutOfRangeException("value");
                }
                this.ViewState["ImageAlign"] = value;
            }
        }

        /// <summary>
        /// [禁用Enabled属性在任何位置编辑。]
        /// </summary>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override bool Enabled
        {
            get
            {
                return base.Enabled;
            }
            set
            {
                base.Enabled = value;
            }
        }

        /// <summary>
        /// [禁用Width属性在任何位置编辑。]
        /// </summary>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override Unit Width
        {
            get
            {
                return Unit.Empty;
            }
        }

        /// <summary>
        /// [禁用Height属性在任何位置编辑。]
        /// </summary>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override Unit Height
        {
            get
            {
                return Unit.Empty;
            }
        }

        /// <summary>
        /// 获取或设置是否允许采用数字字符集。
        /// </summary>
        [DefaultValue(true), Description("获取或设置是否允许采用数字字符集。")]
        public bool EnableNumericCharset
        {
            get
            {
                if (this.ViewState["EnableNumericCharset"] != null)
                {
                    return (bool)this.ViewState["EnableNumericCharset"];
                }
                return true;
            }
            set
            {
                this.ViewState["EnableNumericCharset"] = value;
            }
        }

        /// <summary>
        /// 获取或设置是否允许采用小写英文字母字符集。
        /// </summary>
        [DefaultValue(false), Description("获取或设置是否允许采用小写英文字母字符集。")]
        public bool EnableLowercaseCharset
        {
            get
            {
                if (this.ViewState["EnableLowercaseCharset"] != null)
                {
                    return (bool)this.ViewState["EnableLowercaseCharset"];
                }
                return false;
            }
            set
            {
                this.ViewState["EnableLowercaseCharset"] = value;
            }
        }

        /// <summary>
        /// 获取或设置是否允许采用大写英文字母字符集。
        /// </summary>
        [DefaultValue(false), Description("获取或设置是否允许采用大写英文字母字符集。")]
        public bool EnableUppercaseCharset
        {
            get
            {
                if (this.ViewState["EnableUppercaseCharset"] != null)
                {
                    return (bool)this.ViewState["EnableUppercaseCharset"];
                }
                return false;
            }
            set
            {
                this.ViewState["EnableUppercaseCharset"] = value;
            }
        }

        /// <summary>
        /// 获取或设置是否允许采用简体中文字符集。
        /// </summary>
        [DefaultValue(false), Description("获取或设置是否允许采用简体中文字符集。")]
        public bool EnableChineseCharset
        {
            get
            {
                if (this.ViewState["EnableChineseCharset"] != null)
                {
                    return (bool)this.ViewState["EnableChineseCharset"];
                }
                return false;
            }
            set
            {
                this.ViewState["EnableChineseCharset"] = value;
            }
        }

        /// <summary>
        /// 获取或设置自定义字符集。
        /// </summary>
        [DefaultValue(""), Description("获取或设置自定义字符集。")]
        public string CustomCharset
        {
            get
            {
                if (this.ViewState["CustomCharset"] != null)
                {
                    return (string)this.ViewState["CustomCharset"];
                }
                return string.Empty;
            }
            set
            {
                this.ViewState["CustomCharset"] = value;
            }
        }

        /// <summary>
        /// 验证输入字符串是否符合图片所示要求。根据CaseSensitive规定是否区分大小写。
        /// </summary>
        /// <param name="Input">输入待验证的字符串。</param>
        /// <returns>如果验证符合要求,则返回true,否则返回false。</returns>
        public bool VerifyInput(string Input)
        {
            bool flg = false;
            if (this.CaseSensitive)
            {
                flg = this.MD5Code == System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(Input, "md5");
                if (string.IsNullOrEmpty(this.Page.Request["vrfc"]))
                {
                    //生成新的验证码。
                    try
                    {
                        char[] charset = this.CreateUsedCharset();
                        string OCode = this.GenerateCodeValue(charset, this.CodeLength);
                        this.EncryptCodeValue(OCode);
                    }
                    catch
                    {
                        return false;
                    }
                }
            }
            else
            {
                flg = this.MD5Code == System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(Input.ToLower(), "md5");
                if (string.IsNullOrEmpty(this.Page.Request["vrfc"]))
                {
                    //生成新的验证码。
                    try
                    {
                        char[] charset = this.CreateUsedCharset();
                        string OCode = this.GenerateCodeValue(charset, this.CodeLength);
                        this.EncryptCodeValue(OCode);
                    }
                    catch
                    {
                        return false;
                    }
                }
            }
            return flg;
        }

        /// <summary>
        /// 验证指定的字符串包含控件所含字符串是否符合图片所示要求。根据CaseSensitive规定是否区分大小写。
        /// </summary>
        /// <param name="TextControl">实现ITextControl接口的字符串输入控件。</param>
        /// <returns>如果验证符合要求,则返回true,否则返回false。</returns>
        public bool VerifyInput(ITextControl TextControl)
        {
            return this.VerifyInput(TextControl.Text);
        }

        /// <summary>
        /// 引发Init事件。
        /// </summary>
        /// <param name="e">包含事件数据的EventArgs对象。</param>
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            this.Init += new EventHandler(VerificationCode_Init);
            this.PreRender += new EventHandler(VerificationCode_PreRender);
        }

        /// <summary>
        /// 引发 PreRender 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 EventArgs 对象。</param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            if (!(this.Page.IsPostBack) && string.IsNullOrEmpty(this.Page.Request["vrfc"]))
            {
                //生成新的验证码。
                try
                {
                    char[] charset = this.CreateUsedCharset();
                    string OCode = this.GenerateCodeValue(charset, this.CodeLength);
                    this.EncryptCodeValue(OCode);
                }
                catch
                {
                    this.EncryptCodeValue(string.Empty);
                }
            }
        }

        void VerificationCode_PreRender(object sender, EventArgs e)
        {
            if (HttpContext.Current != null)
            {
                RenderCodeImage(this.Page.Request, this.Page.Response);
            }
        }

        void VerificationCode_Init(object sender, EventArgs e)
        {
            if (HttpContext.Current != null)
            {
                RenderCodeImage(this.Page.Request, this.Page.Response);
            }
        }

        static void RenderCodeImage(HttpRequest request, HttpResponse response)
        {
            if (request["vrfc"] == null)
            {
                return;
            }
            VerificationCode verCode;
            try
            {
                verCode = new VCodeTransferFormatter().DeserializeToVCodeControl(request["vrfc"]);
            }
            catch
            {
                verCode = null;
            }

            Bitmap bmp;
            if (verCode != null)
            {
                bmp = verCode.GetVerificationCodeImage(verCode);
            }
            else
            {
                bmp = Properties.Resources.GenerateImageError;
            }

            response.Clear();
            try
            {
                if (verCode.ImageFormat == VerificationCodeImageFormat.Gif)
                {
                    response.ContentType = "image/gif";
                    bmp.Save(response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
                }
                else if (verCode.ImageFormat == VerificationCodeImageFormat.Jpeg)
                {
                    response.ContentType = "image/jpeg";

                    System.Drawing.Imaging.EncoderParameters encoderParams = new System.Drawing.Imaging.EncoderParameters();
                    long[] quality = new long[] { Convert.ToInt64(verCode.JpegQualityPercentage) };
                    System.Drawing.Imaging.EncoderParameter encoderParam = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
                    encoderParams.Param[0] = encoderParam;
                    System.Drawing.Imaging.ImageCodecInfo[] arrayICI = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
                    System.Drawing.Imaging.ImageCodecInfo jpegICI = null;
                    for (int fwd = 0; fwd < arrayICI.Length - 1; fwd++)
                    {
                        if (arrayICI[fwd].FormatDescription.Equals("JPEG"))
                        {
                            jpegICI = arrayICI[fwd];
                            break;
                        }
                    }

                    if (jpegICI != null)
                    {
                        bmp.Save(response.OutputStream, jpegICI, encoderParams);
                    }
                    else
                    {
                        bmp.Save(response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                    }
                }
            }
            catch
            {
                bmp = Properties.Resources.GenerateImageError;
                response.ContentType = "image/gif";
                bmp.Save(response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
            }
            response.End();
        }

        /// <summary>
        /// 依据当前验证码对象获取验证码图片。
        /// </summary>
        /// <returns>返回图片Bitmap对象。</returns>
        public Bitmap GetVerificationCodeImage()
        {
            return this.GetVerificationCodeImage(this);
        }

        /// <summary>
        /// 依据验证码对象获取验证码图片。
        /// </summary>
        /// <param name="verCode">验证码对象。</param>
        /// <returns>返回图片Bitmap对象。</returns>
        private Bitmap GetVerificationCodeImage(VerificationCode verCode)
        {
            try
            {
                if (verCode == null)
                {
                    return Properties.Resources.GenerateImageError;
                }
                Bitmap tempBmp = new Bitmap(10, 10);
                Graphics tg = Graphics.FromImage(tempBmp);

                TDesEncrpytor tdes = new TDesEncrpytor(verCode.GetMachineKey(), new byte[] { 26, 63, 208, 93, 203, 218, 71, 142 });
                string OCode = string.Empty;
                try
                {
                    OCode = tdes.DecryptFromBase64String(verCode.EncryptedCode);
                }
                catch
                {
                    return Properties.Resources.GenerateImageError;
                }

                if (OCode == string.Empty)
                    return Properties.Resources.GenerateImageError;

                if (verCode.Font.Size.IsEmpty || verCode.Font.Size.Type != FontSize.AsUnit)
                {
                    verCode.Font.Size = FontUnit.Parse("18px");
                }

                SizeF stringRectg = tg.MeasureString(OCode, new Font(verCode.Font.Name, Convert.ToSingle(verCode.Font.Size.Unit.Value), GraphicsUnit.Pixel));
                tg.Dispose();
                tempBmp.Dispose();

                Bitmap bmp = new Bitmap(Convert.ToInt32(stringRectg.Width), Convert.ToInt32(stringRectg.Height));
                Graphics g = Graphics.FromImage(bmp);

                 = System.Drawing. = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;

                g.Clear(verCode.BackColor);

                //绘制背景噪音。
                if (verCode.NoiseRenderMode == VerificationCodeNoiseRenderMode.Back && verCode.NoiseRendingIntensity != 0)
                    this.RenderNoise(g, verCode, bmp.Size, new Pen(verCode.NoiseColor), verCode.NoiseRendingIntensity);

                g.DrawString(OCode, new Font(verCode.Font.Name, Convert.ToSingle(verCode.Font.Size.Unit.Value), GraphicsUnit.Pixel), new SolidBrush(verCode.ForeColor), 0f, 0f);

                //绘制前景噪音。
                if (verCode.NoiseRenderMode == VerificationCodeNoiseRenderMode.Front && verCode.NoiseRendingIntensity != 0)
                    this.RenderNoise(g, verCode, bmp.Size, new Pen(verCode.NoiseColor), verCode.NoiseRendingIntensity);

                g.Dispose();
                return bmp;
            }
            catch
            {
                return Properties.Resources.GenerateImageError;
            }
        }

        /// <summary>
        /// 渲染噪音。
        /// </summary>
        /// <param name="g">渲染要使用的Graphics对象。</param>
        /// <param name="vCode">VerificationCode对象。</param>
        /// <param name="size">画布大小。</param>
        /// <param name="pen">渲染所使用的Pen对象。</param>
        /// <param name="Repeat">渲染单元重复基数。根据此基数和其他参数确定渲染的循环次数。</param>
        protected virtual void RenderNoise(Graphics g, VerificationCode vCode, Size size, Pen pen, int Repeat)
        {
            int width = size.Width;
            int height = size.Height;

            int repeatCount;
            if (vCode.NoiseType == VerificationCodeNoiseType.Spot)
            {
                repeatCount = Convert.ToInt32((width * height / 250) * Repeat);
            }
            else if (vCode.NoiseType == VerificationCodeNoiseType.Line)
            {
                repeatCount = Convert.ToInt32((width * height / 1500) * Repeat);
            }
            else
            {
                repeatCount = 10;
            }

            while (repeatCount-- != 0)
            {
                int sptX = this.rand.Next(width);
                int sptY = this.rand.Next(height);
                int sptX2 = this.rand.Next(width);
                int sptY2 = this.rand.Next(height);
                int sptX3 = this.rand.Next(360);
                int sptY3 = this.rand.Next(360);

                if (vCode.NoiseType == VerificationCodeNoiseType.Spot)
                {
                    g.DrawRectangle(pen, (float)sptX, (float)sptY, 0.5f, 0.5f);
                }
                else if (vCode.NoiseType == VerificationCodeNoiseType.Line)
                {
                    g.DrawLine(pen, sptX, sptY, sptX2, sptY2);
                }
                else
                {
                    return;
                }
            }
        }

        internal string EncryptedCode
        {
            get
            {
                if (this.ViewState["EncryptedCode"] != null)
                {
                    return (string)this.ViewState["EncryptedCode"];
                }
                return string.Empty;
            }
            set
            {
                this.ViewState["EncryptedCode"] = value;
            }
        }

        internal string MD5Code
        {
            get
            {
                if (this.ViewState["MD5Code"] != null)
                {
                    return (string)this.ViewState["MD5Code"];
                }
                return string.Empty;
            }
            set
            {
                this.ViewState["MD5Code"] = value;
            }
        }

        private char[] CreateUsedCharset()
        {
            if (!this.EnableNumericCharset && !this.EnableLowercaseCharset && !this.EnableUppercaseCharset && !this.EnableChineseCharset && this.CustomCharset == string.Empty)
            {
                throw new EmptyCharsetException("No Charset is Specified");
            }

            ArrayList array = new ArrayList();

            if (this.EnableNumericCharset)
                array.AddRange(VerificationCode.NumericCharset);
            if (this.EnableLowercaseCharset)
                array.AddRange(VerificationCode.LowercaseCharset);
            if (this.EnableUppercaseCharset)
                array.AddRange(VerificationCode.UppercaseCharset);
            if (this.EnableChineseCharset)
                array.AddRange(VerificationCode.ChineseCharset);

            array.AddRange(this.CustomCharset.ToCharArray());

            return (char[])array.ToArray(typeof(char));
        }

        private string GenerateCodeValue(char[] Charset, int CodeLength)
        {
            string genstr = string.Empty;

            if (CodeLength < 1)
            {
                throw new CodeLengthException("CodeLength必须是大于1的值。");
            }
            if (CodeLength > 30)
            {
                throw new CodeLengthException("CodeLength过长,必须小于30。");
            }

            for (int i = 0; i < CodeLength; i++)
            {
                genstr += Charset[this.rand.Next(Charset.Length)].ToString();
            }

            return genstr;
        }

        private void EncryptCodeValue(string OriginalValue)
        {
            TDesEncrpytor tdes = new TDesEncrpytor(this.GetMachineKey(), new byte[] { 26, 63, 208, 93, 203, 218, 71, 142 });
            this.EncryptedCode = tdes.EncryptToBase64String(OriginalValue);

            if (this.CaseSensitive)
            {
                this.MD5Code = FormsAuthentication.HashPasswordForStoringInConfigFile(OriginalValue, "md5");
            }
            else
            {
                this.MD5Code = FormsAuthentication.HashPasswordForStoringInConfigFile(OriginalValue.ToLower(), "md5");
            }
        }

        #region IHttpHandler 成员

        /// <summary>
        /// 获取一个值,该值指示其他请求是否可以使用 IHttpHandler 实例。
        /// </summary>
        public bool IsReusable
        {
            get { return false; }
        }

        /// <summary>
        /// 通过实现 IHttpHandler 接口的自定义 HttpHandler 启用 HTTP Web 请求的处理。
        /// </summary>
        /// <param name="context">HttpContext 对象,它提供对用于为 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session 和 Server)的引用。</param>
        public void ProcessRequest(HttpContext context)
        {
            RenderCodeImage(context.Request, context.Response);
        }

        #endregion

        /// <summary>
        /// 创建一个新的 ControlCollection 对象来保存服务器控件的子控件(包括文本控件和服务器控件)。
        /// </summary>
        /// <returns>包含当前服务器控件的子服务器控件的 ControlCollection 对象。</returns>
        protected override ControlCollection CreateControlCollection()
        {
            return new EmptyControlCollection(this);
        }

        /// <summary>
        /// 重新更换验证码图片上的字符。
        /// </summary>
        public void ChangeCode()
        {
            try
            {
                char[] charset = this.CreateUsedCharset();
                string OCode = this.GenerateCodeValue(charset, this.CodeLength);
                this.EncryptCodeValue(OCode);
            }
            catch
            {
            }
        }
    }
}



程序代码:
using System;
using System.Collections.Generic;
using System.Text;

namespace BlogLan.Web.Controls
{
    /// <summary>
    /// 验证码图片格式。
    /// </summary>
    public enum VerificationCodeImageFormat
    {
        Gif,
        Jpeg
    }
}


程序代码:
using System;
using System.Collections.Generic;
using System.Text;

namespace BlogLan.Web.Controls
{
    /// <summary>
    /// 表示噪音渲染的位置模式。
    /// </summary>
    public enum VerificationCodeNoiseRenderMode
    {
        /// <summary>
        /// 噪音在背景上渲染。
        /// </summary>
        Back,
        /// <summary>
        /// 噪音在文字前方渲染。
        /// </summary>
        Front
    }
}


程序代码:
using System;
using System.Collections.Generic;
using System.Text;

namespace BlogLan.Web.Controls
{
    /// <summary>
    /// 噪音类型。
    /// </summary>
    public enum VerificationCodeNoiseType
    {
        /// <summary>
        /// 点
        /// </summary>
        Spot,
        /// <summary>
        /// 线
        /// </summary>
        Line
    }
}


程序代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Web.UI;
using  System.Drawing;
using System.Web.UI.WebControls;

namespace BlogLan.Web.Controls
{
    /// <summary>
    /// 表示为了通过字符串传递VerificationCode对象部分值的格式化提供器。
    /// </summary>
    class VCodeTransferFormatter
    {
        /// <summary>
        /// 从VerificationCode对象将有关变量序列化为Los字符串序列。
        /// </summary>
        /// <param name="VCode">要序列化的VerificationCode对象。</param>
        /// <returns>返回序列化后的字符串。如果输入VerificationCode对象为null,则返回空字符串。</returns>
        public string SerializeFromVCodeControl(VerificationCode VCode)
        {
            if (VCode == null)
                return string.Empty;
            ArrayList al = new ArrayList();

            //要序列化的值。必须和逆序列化排序一致。
            al.Add(VCode.EncryptedCode);
            al.Add(VCode.BackColor);
            al.Add(VCode.ForeColor);
            al.Add(VCode.ImageFormat);
            al.Add(VCode.JpegQualityPercentage);
            al.Add(VCode.Font.Name);
            al.Add(VCode.Font.Size);
            al.Add(VCode.NoiseColor);
            al.Add(VCode.NoiseRenderMode);
            al.Add(VCode.NoiseType);
            al.Add(VCode.NoiseRendingIntensity);

            LosFormatter los = new LosFormatter();

            StringWriter writer = new StringWriter();
            los.Serialize(writer, al);
            string str = writer.ToString();
            writer.Close();
            return str;
        }

        /// <summary>
        /// 从输入字符串逆序列化并装配成VerificationCode对象。
        /// </summary>
        /// <param name="Input">由SerializeFromVCodeControl方法序列化并传递的字符串。</param>
        /// <returns>返回VerificationCode对象。如果逆序列化不成功,将返回null。</returns>
        public VerificationCode DeserializeToVCodeControl(string Input)
        {
            LosFormatter los = new LosFormatter();
            ArrayList al = (ArrayList)los.Deserialize(Input);

            VerificationCode vCode = new VerificationCode();

            //逆序列化。顺序必须与序列化时相同。
            vCode.EncryptedCode = (string)al[0];
            vCode.BackColor = (Color)al[1];
            vCode.ForeColor = (Color)al[2];
            vCode.ImageFormat = (VerificationCodeImageFormat)al[3];
            vCode.JpegQualityPercentage = (int)al[4];
            vCode.Font.Name = (string)al[5];
            vCode.Font.Size = (FontUnit)al[6];
            vCode.NoiseColor = (Color)al[7];
            vCode.NoiseRenderMode = (VerificationCodeNoiseRenderMode)al[8];
            vCode.NoiseType = (VerificationCodeNoiseType)al[9];
            vCode.NoiseRendingIntensity = (int)al[10];


            return vCode;
        }
    }
}


程序代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using  BlogLan.Web.Controls
{
    class TDesEncrpytor
    {
        /// <summary>
        /// 用随机生成的Key和IV初始化TDes加密器。
        /// </summary>
        public TDesEncrpytor()
        {
            this.CreateRandomCodon();
        }

        /// <summary>
        /// 用随机生成的Key和指定的IV初始化TDes加密器。
        /// </summary>
        /// <param name="IV">指定的IV字节数组,必须符合IVSize指定的长度,否则无效。</param>
        public TDesEncrpytor(byte[] IV)
        {
            this.CreateRandomCodon();
            if (IV.Length == IVSize)
                this.TDesIV = IV;
        }

        /// <summary>
        /// 使用指定的Key和IV初始化TDes加密器。
        /// </summary>
        /// <param name="Key">指定的Key字节数组,必须符合KeySize指定的长度,否则无效。</param>
        /// <param name="IV">指定的IV字节数组,必须符合IVSize指定的长度,否则无效。</param>
        public TDesEncrpytor(byte[] Key, byte[] IV)
        {
            this.CreateRandomCodon();
            if (Key.Length == KeySize)
                this.TDesKey = Key;

            if (IV.Length == IVSize)
                this.TDesIV = IV;
        }

        private byte[] tDesKey;
        private byte[] tDesIV;

        public byte[] TDesKey
        {
            get
            {
                return this.tDesKey;
            }
            set
            {
                this.tDesKey = value;
            }
        }

        public byte[] TDesIV
        {
            get
            {
                return this.tDesIV;
            }
            set
            {
                this.tDesIV = value;
            }
        }

        public void CreateRandomCodon()
        {
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            byte[] newkey = new byte[KeySize];
            rng.GetBytes(newkey);
            this.TDesKey = newkey;

            byte[] newiv = new byte[IVSize];
            rng.GetBytes(newiv);
            this.tDesIV = newiv;
        }

        public static readonly int KeySize = 24;
        public static readonly int IVSize = 8;

        public string EncryptToBase64String(string OriginalString)
        {
            MemoryStream outputStream = new MemoryStream();
            CryptoStream cs = new CryptoStream(outputStream, new TripleDESCryptoServiceProvider().CreateEncryptor(this.TDesKey, this.TDesIV), CryptoStreamMode.Write);
            byte[] originalBytes = System.Text.Encoding.UTF8.GetBytes(OriginalString);
            cs.Write(originalBytes, 0, originalBytes.Length);
            cs.FlushFinalBlock();
            return Convert.ToBase64String(outputStream.ToArray());
        }

        public string DecryptFromBase64String(string Base64String)
        {
            try
            {
                MemoryStream outputStream = new MemoryStream();
                CryptoStream cs = new CryptoStream(outputStream, new TripleDESCryptoServiceProvider().CreateDecryptor(this.TDesKey, this.TDesIV), CryptoStreamMode.Write);
                byte[] inputBytes = Convert.FromBase64String(Base64String);
                cs.Write(inputBytes, 0, inputBytes.Length);
                cs.FlushFinalBlock();
                return new System.Text.UTF8Encoding().GetString(outputStream.ToArray());
            }
            catch (Exception ex)
            {
                throw new TDesDecryptException(ex.Message, ex);
            }
        }
    }
}


程序代码:
using System;
using System.Collections.Generic;
using System.Text;

namespace BlogLan.Web.Controls
{
    public class TDesDecryptException : Exception
    {
        public TDesDecryptException(string Message, Exception InnerException)
            : base(Message, InnerException)
        {
        }
    }
}


程序代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.Design;
using System.Web.UI;
using  System.Drawing;
using System.Drawing.Imaging;

namespace BlogLan.Web.Controls.Designer
{
    public class VerificationCodeDesigner : ControlDesigner
    {
        private VerificationCode vCode;

        public override bool AllowResize
        {
            get
            {
                return false;
            }
        }

        public override string GetDesignTimeHtml()
        {
            HtmlTextWriter writer = new HtmlTextWriter(new StringWriter());

            this.vCode.GetDesignTimeCode(writer);
            string result = writer.InnerWriter.ToString();
            writer.Close();

            return result;
            //return base.GetDesignTimeHtml();
        }

        public override void Initialize( component)
        {
            if (!(component is VerificationCode))
            {
                throw new ArgumentException("Component must be a CerificationCode WebControl");
            }
            this.vCode = (VerificationCode)component;
            base.Initialize(component);
        }
    }
}


以上已经是完备的代码,并且添加了大量注释。
声明一下,以上代码都是自己写的。贴出着段代码的意义在于激发各位的思考解决问题的能力。
希望有所用。
搜索更多相关主题的帖子: 验证码控件 
2008-10-09 11:44
小瘪三的烦恼
Rank: 1
等 级:新手上路
帖 子:86
专家分:3
注 册:2008-9-20
收藏
得分:0 
不错。。接收了!!
2008-10-10 09:26
球球
Rank: 6Rank: 6
等 级:贵宾
威 望:27
帖 子:1146
专家分:265
注 册:2005-11-28
收藏
得分:0 
支持!~~

好累
2008-10-10 17:54
bygg
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:乖乖的心中
等 级:版主
威 望:241
帖 子:13555
专家分:3076
注 册:2006-10-23
收藏
得分:0 
厉害...学习一下.呵

飘过~~
2008-10-11 18:53
zhw511006
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2008-10-12
收藏
得分:0 
谢谢分享,收藏了!

宝剑锋从磨砺出,梅花香子苦寒来!
低调做人,坦诚待人,正直为人!
2008-10-12 10:30
cc2832
Rank: 1
等 级:新手上路
帖 子:44
专家分:0
注 册:2008-9-16
收藏
得分:0 
不错!顶啊
2008-10-13 07:48
tan502407
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2008-10-13
收藏
得分:0 
好东西哦。呵呵~顶了
2008-10-13 08:51
drychq
Rank: 1
等 级:新手上路
帖 子:114
专家分:0
注 册:2007-10-30
收藏
得分:0 
太强了。。。。
2008-10-13 22:00
sky263
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2008-10-15
收藏
得分:0 
不错,顶起
2008-10-15 22:22
mustcome
Rank: 2
等 级:论坛游民
帖 子:25
专家分:10
注 册:2007-11-10
收藏
得分:0 
强啊
2008-10-15 22:47
快速回复:最新发布,验证码控件,绝对原创
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.065790 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved