黑马程序员技术交流社区

标题: ASP.NET随机验证码 汉字验证 (三) [打印本页]

作者: 穷傻呆丑萌    时间: 2013-7-31 00:35
标题: ASP.NET随机验证码 汉字验证 (三)
好吧   前面发那个帖子图片都不能看。。抱歉了。。。。
现在又重新弄一次 发现 图片上传上去很模糊不是很清楚 ,也不知道为什么 。
然后放弃直接上图了  。。。打开环境,直接把代码复制过来了。。。。我想这样肯定就清楚了吧、、、、
结果字数超出范围了。。好吧  无比纠结
这个相对其上个帖子来说要好一点吧
大晚上的又重新弄了一次。。。如果版主看到  能不能考虑多给几个技术分。。。。。哈哈  先感谢一下
弄这个帖子。真心好累啊。。。。。不过学到了很多。。很有满足感 。。。哈哈。。。。别的不说。。直接上代码了。。。

还有 各位大神  看到了请多多指出不足或者错误的地方。。。供大家学习。。。。




随着人们对网络安全的日益重视,验证码技术的发展也越来越迅速,通常情况下,验证码有一下集中验证方式:
1.4为数字验证码,,这种严重法师通常是一组随机的数字字符串,4位数字验证码是最原始的验证码,验证原理比较简单,验证作用也不是很大,对网络黑客的安全防范作用也不是很强,因此在网站应用中也很少见。
2.GIF格式验证码,目前常用的的随机数字图片验证码,图片上的字符主要有文字和数字组成,紫檀没有太多的变化,验证作用比4为数字验证码要好一些,CSDN网站用户登录就是用GIF格式的验证码。
3.PNG格式验证码,这种验证方式验证码的图片用随机数字与随机大写英文字母组成,整个构图有点张扬,没刷新一次每个字符的位子还会变,偶时候刷新出的图片让人很难辨认,。使用PNG格式验证码比使用GIF验证格式更安全,QQ网站用户登录就是用PNG格式的验证码。
4.BMP格式验证码,这种验证方式的验证码有随机数字大写英文字母和随机干扰图素组成,BMP格式的验证码能够改变不同的随机位子,有时候还可以变换随机的字体。
5.JPG格式的验证码,这种验证码是有随机英文字母,随机颜色,随机位置和程度组成,Google的Gmail注册时使用的就是JPG格式的验证码。



再下来的是最难的一个了汉字验证码。。。也是现在我个人掌握还不是很牢固的一个。。。。还需要多加练习了

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Text;
using System.Drawing;

public partial class GetValid : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            string validateNum = GetValids();                 //成生4位随机字符串
            CreateImage(validateNum);                         //将生成的随机字符串绘成图片
            Session["ValidNums"] = validateNum;               //保存验证码
        }
    }
    public static  string GetValids()
    {
        //获取GB2312编码页(表)     
        Encoding gb = Encoding.GetEncoding("gb2312");

        //调用函数产生4个随机中文汉字编码     
        object[] bytes = CreateRegionCode(4);

        //根据汉字编码的字节数组解码出中文汉字   
        string s = String.Empty;
        foreach (object byt in bytes)
        {
            string str1 = gb.GetString((byte[])Convert.ChangeType(byt, typeof(byte[])));
            s = s + str1;
        }

        //输出的控制台     
        return s;
    }
    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, 8);
            }
            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 void CreateImage(string validateNum)
    {
        if (validateNum == null || validateNum.Trim() == String.Empty)
            return;
        //生成Bitmap图像
        System.Drawing.Bitmap image = new System.Drawing.Bitmap(validateNum.Length * 12 + 10, 22);
        Graphics g = Graphics.FromImage(image);

        try
        {
            //生成随机生成器
            Random random = new Random();

            //清空图片背景色
            g.Clear(Color.White);

            //画图片的背景噪音线
            for (int i = 0; i < 25; 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.Coral), x1, y1, x2, y2);
            }

            Font font = new System.Drawing.Font("Arial", 8);
            System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2f, true);
            g.DrawString(validateNum, font, brush, 2, 2);

            //画图片的前景噪音点
            for (int i = 0; i < 100; 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.ContentType = "image/Gif";
            Response.BinaryWrite(ms.ToArray());
        }
        finally
        {
            g.Dispose();
            image.Dispose();
        }
    }
}


protected void Button1_Click(object sender, EventArgs e)
    {
        string num = this.TextBox3.Text.Trim();
        string ValidNums = Session["ValidNums"].ToString();      //获得验证码
        if (ValidNums == num.ToUpper())                          //比较验证码
        {
            this.Page.RegisterStartupScript("ss", "<script>alert('恭喜您已经成功通过验证!')</script>");
        }
        else
        {
            this.Page.RegisterStartupScript("ss", "<script>alert('您输入的验证码不正确!')</script>");
        }
    }
















欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2