Chinaunix首页 | 论坛 | 博客
  • 博客访问: 493206
  • 博文数量: 23
  • 博客积分: 7960
  • 博客等级: 少将
  • 技术积分: 1345
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-11 04:05
文章分类

全部博文(23)

文章存档

2010年(1)

2009年(2)

2008年(20)

我的朋友

分类: 系统运维

2008-09-07 13:00:34

实现原理及步骤:
 
    1、下载目标验证码到内存
    2、将验证码图片转化为黑白
    3、取黑白像素点的深度对比出验证码
 
以下为.net 3.0下的一个实例 (分析出验证码并自动提交注册)
 

using System;
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.Drawing;
using System.Drawing.Imaging;
using System.Net;
using System.Drawing.Drawing2D;
using System.IO;
using System.Text;
using System.Collections;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            if (ComFun.Fail > 10)
            {
                string info = "当前注册成功:" + ComFun.Success.ToString() + "个
当前注册失败: "
+ ComFun.Fail.ToString() + "个";

                Response.Write(info);
                Response.End();
            }

            //提交注册页面地址

            string Url = "";
            //验证码地址

            string ValidateCodeUrl = "";

            HttpWebResponse resp;
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(ValidateCodeUrl);
            req.CookieContainer = ComFun.cookie;
            req.Timeout = 150000;//毫秒

            resp = (HttpWebResponse)req.GetResponse();

            //得到验证码图片

            Bitmap bitmap = new System.Drawing.Bitmap(resp.GetResponseStream());

            if (bitmap == null)
            {
                Response.Redirect("Default.aspx");

                return;
            }

            //分析得到验证码

            int[] Key = GetKey(bitmap);

            bitmap.Clone();
            bitmap.Dispose();

            //页面提交参数

            string go = "1";
            string email = "bqev" + new Random().Next(0, 100000).ToString() + "q@yaaasdfas.com";//随即生成邮箱地址

            string password = "123456";
            string chkpass = "123456";
            string nickname = "asd315yb";
            string sex = "m";//f

            string year = "1980";
            string month = "21";
            string day = "2111";
            string height = "178";
            string marriage = "1";
            string degree = "70";
            string income = "50";
            //string contact_limit = "true";

            string province = "11";
            string city = "1101";
            string mobile = "13691291985";
            string needage_min = "18";
            string needage_max = "20";
            string needheight_min = "150";
            string needheight_max = "170";
            string needmarriage = "1";
            string needdegree = "20";
            //string nedegree_up = "true";

            string neprovince = "11";
            string necity = "1101";
            string validate_code = "";//验证码

            string note = "AAAAAAAAAA AAAAAAAAAA AAAAAAAAAA AAAAAAAAAA";//20-1000字

            string readme = "on";

            for (int i = 0; i < Key.Length; i++)
            {
                validate_code += Key[i].ToString();
            }

            StringBuilder PostData = new StringBuilder();

            PostData
                .Append("go=").Append(go)
                .Append("&email=").Append(email)
                .Append("&password=").Append(password)
                .Append("&chkpass=").Append(chkpass)
                .Append("&nickname=").Append(nickname)
                .Append("&sex=").Append(sex)
                .Append("&year=").Append(year)
                .Append("&month=").Append(month)
                .Append("&day=").Append(day)
                .Append("&height=").Append(height)
                .Append("&marriage=").Append(marriage)
                .Append("°ree=").Append(degree)
                .Append("&income=").Append(income)
                //.Append("&contact_limit=").Append(contact_limit)

                .Append("&province=").Append(province)
                .Append("&city=").Append(city)
                .Append("&mobile=").Append(mobile)
                .Append("&needage_min=").Append(needage_min)
                .Append("&needage_max=").Append(needage_max)
                .Append("&needheight_min=").Append(needheight_min)
                .Append("&needheight_max=").Append(needheight_max)
                .Append("&needmarriage=").Append(needmarriage)
                .Append("&needdegree=").Append(needdegree)
                //.Append("&nedegree_up=").Append(nedegree_up)

                .Append("&neprovince=").Append(neprovince)
                .Append("&necity=").Append(necity)
                .Append("&validate_code=").Append(validate_code)
                .Append("¬e=").Append(note)
                .Append("&readme=").Append(readme);

            string Error = null;
            //提交并返回结果

            string RegResultPage = ComFun.GetPage(Url, PostData.ToString(), "UTF-8", ref Error);

            if (RegResultPage.IndexOf("注册成功") == -1)
            {
                ComFun.Fail++;
            }
            else
            {
                ComFun.Success++;
            }

            Response.Redirect("Default.aspx");
        }
    }

    ///



    /// 图像切割

    ///


    public int[] GetKey(Bitmap bitmap)
    {
        //宽度

        int width = bitmap.Width;
        //高度

        int height = bitmap.Height;
        //图像转化为黑白

        bitmap = ConvertToGrayscale(bitmap);

        int[,] xArray = new int[5, 2];//5个验证码起始x坐标

        int[,] yArray = new int[5, 2];//5个验证码起始y坐标


        //初始化验证码起始坐标

        for (int i = 0; i < 5; i++)
        {
            for (int j = 0; j < 2; j++)
            {
                xArray[i, j] = 0;
                yArray[i, j] = 0;
            }
        }

        int isStart = 0;//是否开始

        int lieHei = 0;//是否有黑点

        int lieBai = 0;//是否有白点

        int nX = 0;//第n个验证码,X方向看

        int[,] PicBlackPixelY = new int[5, height];//5个验证码黑点像素点集合Y坐标

        StringBuilder sb = new StringBuilder();//图片全部黑点坐标临时存储


        for (int X = 0; X < width; X++) //x坐标

        {
            for (int Y = 1; Y < height - 1; Y++) //y坐标

            {
                //点(X,Y)的颜色

                if (Y >= 1 && Y <= height - 2)
                {
                    string color = ColorTranslator.ToHtml(bitmap.GetPixel(X, Y));
                    if (ShoveEL._Convert.StrToInt(color.Substring(1, 1), -1) >= 0 && ShoveEL._Convert.StrToInt(color.Substring(1, 1), -1) < 7)
                    {
                        lieHei = 1;//存在黑点

                        try
                        {
                            PicBlackPixelY[nX, Y] = Y;
                        }
                        catch { }
                    }
                    else
                    {
                        lieBai = 1;//存在白点

                    }
                }
            }

            if (lieBai == 1 && lieHei == 1 && isStart == 0)//黑白相间

            {
                try
                {
                    xArray[nX, 0] = X;
                }
                catch { }
                isStart = 1;
            }

            if (lieBai == 1 && lieHei == 0 && isStart == 1)//全白

            {
                try
                {
                    xArray[nX, 1] = X;
                }
                catch { }
                isStart = 0;//结束

                nX++;
            }

            lieHei = 0;
            lieBai = 0;
        }

        //算出5个验证码y轴方向 最大最小 黑点坐标

        for (int i = 0; i < 5; i++)
        {
            int minY = height;
            int maxY = 0;

            for (int j = 0; j < height; j++)
            {
                if (PicBlackPixelY[i, j] < minY && PicBlackPixelY[i, j] > 0)
                {
                    minY = PicBlackPixelY[i, j];
                }

                if (PicBlackPixelY[i, j] > maxY)
                {
                    maxY = PicBlackPixelY[i, j];
                }
            }

            yArray[i, 0] = minY - 1;
            yArray[i, 1] = maxY + 1;
        }

        for (int i = 0; i < 5; i++)
        {
            width = xArray[i, 1] - xArray[i, 0];
            height = yArray[i, 1] - yArray[i, 0];

            for (int offsetX = 0; offsetX < width; offsetX++) //x坐标

            {
                for (int offsetY = 0; offsetY < height; offsetY++) //y坐标

                {
                    //获得验证码图片点的颜色

                    string color = ColorTranslator.ToHtml(bitmap.GetPixel(xArray[i, 0] + offsetX, yArray[i, 0] + offsetY));

                    if (ShoveEL._Convert.StrToInt(color.Substring(1, 1), -1) >= 0 && ShoveEL._Convert.StrToInt(color.Substring(1, 1), -1) < 8)
                    {
                        sb.Append(offsetX.ToString()).Append(offsetY.ToString()).Append(",");
                    }
                }
            }
            sb.Remove(sb.Length - 1, 1);
            sb.AppendLine("|");
        }

        bitmap.Dispose();

        //得到验证码

        int[] Key = ComparePic(sb);

        return Key;
    }

    ///

    /// 比较图片相似度已确定验证码对应数字

    ///


    ///

    ///

    private int[] ComparePic(StringBuilder sb)
    {
        //特征图片像素点集合:数字0-9像素点集合,做对比用

        ArrayList arr = new ArrayList();

        arr.Add(new int[] { 03, 04, 05, 06, 07, 08, 09, 12, 13, 14, 15, 16, 17, 19, 110, 21, 22, 23, 24, 25, 26, 27, 28, 29, 210, 211, 31, 32, 33, 39, 310, 311, 41, 42, 45, 411, 51, 53, 59, 510, 511, 62, 63, 64, 66, 67, 68, 610, 611, 72, 73, 74, 75, 76, 77, 78, 79, 710, 83, 84, 85, 86, 87, 88, 89 });
        arr.Add(new int[] { 04, 05, 13, 14, 15, 22, 23, 24, 31, 32, 33, 34, 35, 36, 37, 38, 39, 310, 311, 41, 42, 43, 44, 45, 46, 47, 48, 49, 410, 411, 51, 52, 53, 54, 55, 57, 58, 59, 510, 511 });
        arr.Add(new int[] { 04, 010, 011, 13, 14, 19, 110, 111, 21, 22, 23, 24, 28, 29, 210, 211, 31, 32, 33, 37, 38, 39, 310, 311, 41, 42, 46, 47, 48, 49, 410, 411, 51, 53, 55, 56, 57, 58, 510, 511, 61, 62, 63, 64, 65, 66, 67, 610, 611, 71, 72, 73, 74, 75, 76, 710, 711, 82, 83, 84, 85, 810, 811 });
        arr.Add(new int[] { 02, 03, 09, 010, 11, 12, 13, 18, 19, 110, 111, 21, 22, 23, 29, 210, 211, 31, 32, 35, 36, 310, 311, 41, 42, 45, 46, 410, 411, 51, 52, 53, 54, 55, 56, 57, 59, 510, 511, 61, 62, 63, 64, 65, 66, 67, 68, 69, 610, 611, 72, 73, 74, 76, 77, 78, 79, 710, 87, 88, 89 });
        arr.Add(new int[] { 08, 09, 16, 17, 18, 19, 25, 26, 28, 29, 34, 35, 36, 37, 38, 39, 43, 44, 45, 48, 49, 52, 53, 54, 58, 59, 61, 62, 63, 64, 65, 66, 67, 68, 610, 611, 71, 73, 74, 75, 76, 77, 78, 79, 710, 711, 81, 82, 83, 84, 85, 86, 87, 88, 89, 811, 98, 99 });
        arr.Add(new int[] { 04, 05, 09, 11, 12, 13, 14, 15, 16, 19, 110, 21, 22, 23, 24, 25, 26, 29, 210, 32, 33, 34, 35, 39, 310, 311, 41, 42, 44, 45, 410, 411, 51, 52, 54, 55, 59, 510, 511, 61, 62, 64, 65, 66, 67, 68, 69, 610, 611, 71, 72, 75, 76, 77, 78, 79, 710, 81, 82, 85, 86, 87, 88, 89 });
        arr.Add(new int[] { 04, 05, 06, 07, 08, 09, 12, 13, 14, 15, 16, 17, 18, 19, 110, 21, 22, 23, 25, 26, 27, 28, 29, 210, 31, 32, 33, 36, 37, 39, 310, 311, 41, 42, 45, 46, 410, 411, 51, 52, 55, 510, 511, 61, 62, 63, 65, 66, 67, 68, 69, 610, 611, 72, 73, 76, 77, 78, 79, 710, 83, 86, 87, 88, 89, 810 });
        arr.Add(new int[] { 01, 02, 11, 12, 21, 22, 28, 29, 210, 211, 31, 32, 37, 38, 39, 310, 41, 42, 44, 45, 46, 47, 48, 49, 410, 411, 51, 53, 54, 55, 56, 57, 58, 61, 62, 63, 64, 65, 71, 72, 73, 81, 82 });
        arr.Add(new int[] { 02, 03, 04, 07, 08, 09, 010, 12, 13, 14, 16, 17, 18, 19, 110, 111, 21, 22, 23, 24, 25, 26, 27, 28, 29, 210, 211, 31, 32, 33, 35, 36, 37, 39, 310, 311, 41, 42, 45, 46, 410, 411, 51, 52, 55, 56, 57, 59, 510, 511, 61, 62, 63, 64, 65, 66, 67, 68, 69, 610, 611, 72, 74, 75, 76, 77, 78, 710, 82, 83, 84, 88, 89 });
        arr.Add(new int[] { 03, 05, 09, 12, 13, 14, 15, 16, 17, 19, 110, 21, 22, 23, 24, 25, 26, 29, 210, 211, 31, 32, 33, 35, 36, 37, 39, 310, 311, 41, 42, 46, 47, 410, 411, 51, 52, 56, 59, 510, 511, 61, 63, 64, 65, 66, 67, 68, 69, 610, 72, 73, 74, 75, 76, 77, 78, 79, 710, 83, 84, 85, 86, 87, 88, 89 });

        int[] Key = new int[5];

        string[] picPixel = sb.ToString().Split('|');//各验证码点集合


        //对比相似程度

        for (int i = 0; i < 5; i++)
        {
            string[] p = picPixel[i].Split(',');

            for (int j = 0; j < 10; j++)
            {
                int[] B = (int[])(arr[j]);

                try
                {
                    //选出当前验证码跟特征图片相同的点

                    var q = from a in p join b in B on Convert.ToInt32(a) equals b select b;

                    //相似程度 = 相似像素点数/当前验证数字像素数

                    double xs = (double)q.Count<int>() / (double)p.Length;

                    if (xs > 0.9)//90%相似,表明该图片就是该数字了

                    {
                        Key[i] = j;

                        break;
                    }
                }
                catch { }
            }
        }

        return Key;
    }

    ///

    /// 放大缩小图片尺寸

    ///


    ///

    ///

    ///

    ///

    public void PicSized(string picPath, string reSizePicPath, int iSize, ImageFormat format)
    {
        Bitmap originBmp = new Bitmap(picPath);

        int w = originBmp.Width * iSize;
        int h = originBmp.Height * iSize;

        Bitmap resizedBmp = new Bitmap(w, h);
        Graphics g = Graphics.FromImage(resizedBmp);

        //设置高质量插值法

        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
        //设置高质量,低速度呈现平滑程度

        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
        g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
        //消除锯齿

        g.SmoothingMode = SmoothingMode.AntiAlias;

        g.DrawImage(originBmp, new Rectangle(0, 0, w, h), new Rectangle(0, 0, originBmp.Width, originBmp.Height), GraphicsUnit.Pixel);

        resizedBmp.Save(reSizePicPath, format);

        g.Dispose();
        resizedBmp.Dispose();
        originBmp.Dispose();
    }

    ///

    /// 彩色图片转化为黑白

    ///


    ///

    ///

    public Bitmap ConvertToGrayscale(Bitmap bitmap)
    {
        Bitmap bm = new Bitmap(bitmap.Width, bitmap.Height);

        for (int y = 0; y < bm.Height; y++)
        {
            for (int x = 0; x < bm.Width; x++)
            {
                Color c = bitmap.GetPixel(x, y);

                int rgb = (int)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11);

                bm.SetPixel(x, y, Color.FromArgb(rgb, rgb, rgb));
            }
        }

        return bm;
    }
}

阅读(5475) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

fony2059232013-01-16 15:04:01

請問一下 關於文中的req.CookieContainer = ComFun.cookie 的ComFun從何而來??
還有ShoveEL._Convert ShoveEL 也是....