Verify.cs
上传用户:xhd1221
上传日期:2022-05-28
资源大小:186k
文件大小:19k
源码类别:

外挂编程

开发平台:

C/C++

  1. using System;
  2. namespace QQWinFarm
  3. {
  4.     /// <summary> 
  5.     /// yzm 的摘要说明。 
  6.     /// </summary> 
  7.     public class Verify
  8.     {
  9.         public Verify(System.Drawing.Bitmap pic)
  10.         {
  11.             this.bp = pic;
  12.         }
  13.         /// <summary> 
  14.         /// 将一个int值存入到4个字节的字节数组(从高地址开始转换,最高地址的值以无符号整型参与"与运算") 
  15.         /// </summary> 
  16.         /// <param name="thevalue">要处理的int值</param> 
  17.         /// <param name="thebuff">存放信息的字符数组</param> 
  18.         public static void getbytesfromint(int thevalue, byte[] thebuff)
  19.         {
  20.             long v1 = 0; long v2 = 0; long v3 = 0; long v4 = 0;
  21.             uint b1 = (uint)4278190080; uint b2 = (uint)16711680; uint b3 = (uint)65280; uint b4 = (uint)255;
  22.             v1 = thevalue & b1;
  23.             v2 = thevalue & b2;
  24.             v3 = thevalue & b3;
  25.             v4 = thevalue & b4;
  26.             thebuff[0] = (byte)(v1 >> 24);
  27.             thebuff[1] = (byte)(v2 >> 16);
  28.             thebuff[2] = (byte)(v3 >> 8);
  29.             thebuff[3] = (byte)v4;
  30.         }
  31.         /// <summary> 
  32.         /// 将一个ushort值存入到2个字节的字节数组(从高地址开始转换,最高地址的值以无符号整型参与"与运算") 
  33.         /// </summary> 
  34.         /// <param name="thevalue">要处理的ushort值</param> 
  35.         /// <param name="thebuff">存放信息的字符数组</param> 
  36.         public static void getbytesfromushort(ushort thevalue, byte[] thebuff)
  37.         {
  38.             ushort v1 = 0; ushort v2 = 0;
  39.             ushort b1 = (ushort)65280; ushort b2 = (ushort)255;
  40.             v1 = (ushort)(thevalue & b1);
  41.             v2 = (ushort)(thevalue & b2);
  42.             thebuff[0] = (byte)(v1 >> 8);
  43.             thebuff[1] = (byte)(v2);
  44.         }
  45.         /// <summary> 
  46.         /// 将4个字节的字节数组转换成一个int值 
  47.         /// </summary> 
  48.         /// <param name="thebuff">字符数组</param> 
  49.         /// <returns></returns> 
  50.         public static int getintfrombyte(byte[] thebuff)
  51.         {
  52.             int jieguo = 0;
  53.             long mid = 0;
  54.             long m1 = 0; long m2 = 0; long m3 = 0; long m4 = 0;
  55.             m1 = (thebuff[0] << 24);
  56.             m2 = (thebuff[1] << 16);
  57.             m3 = (thebuff[2] << 8);
  58.             m4 = thebuff[3];
  59.             mid = m1 + m2 + m3 + m4;
  60.             jieguo = (int)mid;
  61.             return jieguo;
  62.         }
  63.         /// <summary> 
  64.         /// 将2个字节的字节数组转换成一个ushort值 
  65.         /// </summary> 
  66.         /// <param name="thebuff">字符数组</param> 
  67.         /// <returns></returns> 
  68.         public static ushort getushortfrombyte(byte[] thebuff)
  69.         {
  70.             int jieguo1 = 0;
  71.             jieguo1 = (thebuff[0] << 8) + thebuff[1];
  72.             ushort jieguo = (ushort)jieguo1;
  73.             return jieguo;
  74.         }
  75.         /// <summary> 
  76.         /// 将内存中的数据写入硬盘(保存特征库) 
  77.         /// </summary> 
  78.         /// <param name="thefile">保存的位置</param> 
  79.         public static void writetofile(string thefile)
  80.         {
  81.             System.IO.FileStream fs = new System.IO.FileStream(thefile, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite);
  82.             byte[] buff0 = new byte[4];
  83.             getbytesfromint(datanum, buff0);
  84.             fs.Write(buff0, 0, 4);
  85.             for (int ii = 0; ii < datanum; ii++)
  86.             {
  87.                 for (int jj = 0; jj < 20; jj++)
  88.                 {
  89.                     byte[] buff = new byte[2];
  90.                     getbytesfromushort(datap[ii, jj], buff);
  91.                     fs.Write(buff, 0, 2);
  92.                 }
  93.                 fs.WriteByte(dataxy[ii, 0]);
  94.                 fs.WriteByte(dataxy[ii, 1]);
  95.                 fs.WriteByte(datachar[ii]);
  96.             }
  97.             fs.Close();
  98.         }
  99.         /// <summary> 
  100.         /// 从文件中读取信息,并保存在内存中相应的位置 
  101.         /// </summary> 
  102.         /// <param name="thefile">特征库文件</param> 
  103.         public static void readfromfile(string thefile)
  104.         {
  105.             int allnum = 0;
  106.             byte[] buff = new byte[4];
  107.             System.IO.FileStream fs = new System.IO.FileStream(thefile, System.IO.FileMode.Open, System.IO.FileAccess.Read);
  108.             fs.Read(buff, 0, 4);
  109.             allnum = getintfrombyte(buff);
  110.             byte[] buff0 = new byte[2];
  111.             for (int ii = 0; ii < allnum; ii++)
  112.             {
  113.                 for (int jj = 0; jj < 20; jj++)
  114.                 {
  115.                     fs.Read(buff0, 0, 2);
  116.                     datap[ii, jj] = getushortfrombyte(buff0);
  117.                 }
  118.                 fs.Read(buff0, 0, 1);
  119.                 dataxy[ii, 0] = buff0[0];
  120.                 fs.Read(buff0, 0, 1);
  121.                 dataxy[ii, 1] = buff0[0];
  122.                 fs.Read(buff0, 0, 1);
  123.                 datachar[ii] = buff0[0];
  124.             }
  125.             datanum = allnum;
  126.             fs.Close();
  127.         }
  128.         /// <summary> 
  129.         /// 验证码图片 
  130.         /// </summary> 
  131.         public System.Drawing.Bitmap bp = new System.Drawing.Bitmap(49, 20);
  132.         /// <summary> 
  133.         /// 特征库的长度 
  134.         /// </summary> 
  135.         public static int datanum = 0;
  136.         /// <summary> 
  137.         /// 特征库数据 
  138.         /// </summary> 
  139.         public static ushort[,] datap = new ushort[100000, 20];
  140.         /// <summary> 
  141.         /// 长度与高度 
  142.         /// </summary> 
  143.         public static byte[,] dataxy = new byte[100000, 2];
  144.         /// <summary> 
  145.         /// 对应的字符 
  146.         /// </summary> 
  147.         public static byte[] datachar = new byte[100000];
  148.         /// <summary> 
  149.         /// 等待处理的数据 
  150.         /// </summary> 
  151.         public ushort[] datapic = new ushort[20];
  152.         /// <summary> 
  153.         /// 有效长度 
  154.         /// </summary> 
  155.         public byte xlpic = 0;
  156.         /// <summary> 
  157.         /// 有效宽度 
  158.         /// </summary> 
  159.         public byte ylpic = 0;
  160.         /// <summary> 
  161.         /// 检索特征库中存在的记录 
  162.         /// </summary> 
  163.         public string getchar()
  164.         {
  165.             //如果查找不到,就返回空串 
  166.             string jieguo = "";
  167.             for (int ii = 0; ii < datanum; ii++)
  168.             {
  169.                 //统计一共有多少行的像素有差异,如果在4行以内就认为是存在该记录 
  170.                 //这种方法比较原始,但比较适合多线程时的运行,因为程序只进行简单的逻辑比较 
  171.                 //如果能够收集更多的特征库,识别率可以达到80%以上 
  172.                 //(此时可能需要将特征库的容量提高到15W个或以上) 
  173.                 //当然也可以改进品配算法(如使用关键点品配),以用较少的特征库达到较高的识别率,但 
  174.                 //那样有比较大的机会造成识别错误并且多线程时占用较多CPU时间。 
  175.                 int notsamenum = 0;
  176.                 if (dataxy[ii, 0] != xlpic || dataxy[ii, 1] != ylpic)
  177.                 {
  178.                     continue;
  179.                 }
  180.                 for (int jj = 0; jj < 20; jj++)
  181.                 {
  182.                     if (datap[ii, jj] != datapic[jj])
  183.                     {
  184.                         notsamenum++;
  185.                     }
  186.                 }
  187.                 if (notsamenum < 4)
  188.                 {
  189.                     char cj = (char)datachar[ii];
  190.                     return cj.ToString();
  191.                 }
  192.             }
  193.             return jieguo;
  194.         }
  195.         /// <summary> 
  196.         /// 检查特征库中是否已经存在相关记录 
  197.         /// </summary> 
  198.         bool ischardatain()
  199.         {
  200.             bool jieguo = false;
  201.             for (int ii = 0; ii < datanum; ii++)
  202.             {
  203.                 //统计一共有多少行的像素有差异,如果在4行以内就认为是存在该记录 
  204.                 //这种方法比较原始,但比较适合多线程时的运行,因为程序只进行简单的逻辑比较 
  205.                 //如果能够收集更多的特征库,识别率可以达到80%以上 
  206.                 //(此时可能需要将特征库的容量提高到15W个或以上) 
  207.                 //当然也可以改进品配算法(如使用关键点品配),以用较少的特征库达到较高的识别率,但 
  208.                 //那样有比较大的机会造成识别错误并且多线程时占用较多CPU时间。 
  209.                 int notsamenum = 0;
  210.                 if (System.Math.Abs(dataxy[ii, 0] - xlpic) > 1 || System.Math.Abs(dataxy[ii, 1] - ylpic) > 1)
  211.                 {
  212.                     continue;
  213.                 }
  214.                 for (int jj = 0; jj < 20; jj++)
  215.                 {
  216.                     if (datap[ii, jj] != datapic[jj])
  217.                     {
  218.                         notsamenum++;
  219.                     }
  220.                 }
  221.                 if (notsamenum < 4)
  222.                 {
  223.                     string asdasd = ((char)datachar[ii]).ToString();
  224.                     return true;
  225.                 }
  226.             }
  227.             return jieguo;
  228.         }
  229.         /// <summary> 
  230.         /// 添加到特征库中,并暂时将对应的字符置为空格以待人工识别 
  231.         /// </summary> 
  232.         void adddatawithnullchar()
  233.         {
  234.             if (this.ischardatain())
  235.             {
  236.                 return;
  237.             }
  238.             for (int ii = 0; ii < 20; ii++)
  239.             {
  240.                 datap[datanum, ii] = this.datapic[ii];
  241.             }
  242.             //暂时将对应的字符置为空格以待人工识别 
  243.             datachar[datanum] = 32;
  244.             dataxy[datanum, 0] = this.xlpic;
  245.             dataxy[datanum, 1] = this.ylpic;
  246.             datanum++;
  247.         }
  248.         /// <summary> 
  249.         /// 检查验证码图片是否能分成4个部分,如果可以就检查4个字符在特征库中是否已经存在,如果不存在, 
  250.         /// 就添加到特征库中,并暂时将对应的字符置为空格以待人工识别 
  251.         /// </summary> 
  252.         public void writetodata()
  253.         {
  254.             bool[,] picpixel = new bool[bp.Width, bp.Height];
  255.             for (int ii = 0; ii < bp.Width; ii++)
  256.             {
  257.                 for (int jj = 0; jj < bp.Height; jj++)
  258.                 {
  259.                     System.Drawing.Color asd = System.Drawing.Color.FromArgb(200,200,200);
  260.                     System.Drawing.Color asd1 = System.Drawing.Color.FromArgb(211, 60,7);
  261.                     // bp.GetPixel(ii, jj);
  262.                     float asd2, asd3;
  263.                     asd2 = asd.GetBrightness();
  264.                     asd3 = asd1.GetBrightness();
  265.                     //float asd1 = asd.GetBrightness();
  266.                     float asd4 = bp.GetPixel(ii, jj).GetBrightness();
  267.                     if (asd4 < asd2)//bp.GetPixel(ii, jj).GetBrightness() < System.Drawing.Color.FromArgb(207, 255, 255).GetBrightness())
  268.                     {
  269.                         bp.SetPixel(ii, jj, System.Drawing.Color.FromArgb(0, 0, 0));
  270.                         //if(asd4<asd2)
  271.                         picpixel[ii, jj] = true;
  272.                     }
  273.                     else
  274.                     {
  275.                         bp.SetPixel(ii, jj, System.Drawing.Color.FromArgb(255, 255, 255));
  276.                         picpixel[ii, jj] = false;
  277.                     }
  278.                 }
  279.             }
  280.             return;
  281.             
  282.             int[] index = new int[8];
  283.             int indexnum = 0;
  284.             bool black = false;
  285.             for (int ii = 0; ii < bp.Width; ii++)
  286.             {
  287.                 bool haveblack = false;
  288.                 for (int jj = 0; jj < bp.Height; jj++)
  289.                 {
  290.                     if (picpixel[ii, jj])
  291.                     {
  292.                         haveblack = true;
  293.                         break;
  294.                     }
  295.                 }
  296.                 if (haveblack && black == false)
  297.                 {
  298.                     index[indexnum] = ii;
  299.                     indexnum++;
  300.                     black = true;
  301.                 }
  302.                 if (!haveblack && black)
  303.                 {
  304.                     index[indexnum] = ii;
  305.                     indexnum++;
  306.                     black = false;
  307.                 }
  308.             }
  309.             if (indexnum < 7)
  310.             {
  311.                 return;
  312.             }
  313.             if (indexnum == 7)
  314.             {
  315.                 index[7] = 49;
  316.             }
  317.             //**** 
  318.             for (int ii = 0; ii < 4; ii++)
  319.             {
  320.                 int x1 = index[ii * 2];
  321.                 int x2 = index[ii * 2 + 1];
  322.                 int y1 = 0, y2 = 19;
  323.                 bool mb = false;
  324.                 for (int jj = 0; jj < 20; jj++)
  325.                 {
  326.                     for (int kk = x1; kk < x2; kk++)
  327.                     {
  328.                         if (picpixel[kk, jj])
  329.                         {
  330.                             mb = true;
  331.                             break;
  332.                         }
  333.                     }
  334.                     if (mb)
  335.                     {
  336.                         y1 = jj;
  337.                         break;
  338.                     }
  339.                 }
  340.                 mb = false;
  341.                 for (int jj = 19; jj >= 0; jj--)
  342.                 {
  343.                     for (int kk = x1; kk < x2; kk++)
  344.                     {
  345.                         if (picpixel[kk, jj])
  346.                         {
  347.                             mb = true;
  348.                             break;
  349.                         }
  350.                     }
  351.                     if (mb)
  352.                     {
  353.                         y2 = jj;
  354.                         break;
  355.                     }
  356.                 }
  357.                 //**以上是获取有效区域的范围 
  358.                 for (int jj = 0; jj < 20; jj++)
  359.                 {
  360.                     this.datapic[jj] = 0;
  361.                     this.datapic[jj] = 0;
  362.                 }
  363.                 this.xlpic = (byte)(x2 - x1);
  364.                 //如果字符宽度超过16个像素就不予处理 
  365.                 if (xlpic > 16)
  366.                 {
  367.                     continue;
  368.                 }
  369.                 this.ylpic = (byte)(y2 - y1 + 1);
  370.                 int ys = -1;
  371.                 ushort[] addin = new ushort[] { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 };
  372.                 for (int jj = y1; jj <= y2; jj++)
  373.                 {
  374.                     ys++;
  375.                     int xs = -1;
  376.                     for (int kk = x1; kk < x2; kk++)
  377.                     {
  378.                         xs++;
  379.                         if (picpixel[kk, jj])
  380.                         {
  381.                             this.datapic[ys] = (ushort)(this.datapic[ys] + addin[xs]);
  382.                         }
  383.                     }
  384.                 }
  385.                 this.adddatawithnullchar();
  386.             }
  387.             //**** 
  388.         }
  389.         /// <summary> 
  390.         /// 识别图片 
  391.         /// </summary> 
  392.         /// <returns>返回识别结果(如果返回的字符串长度小于4就说明识别失败)</returns> 
  393.         public string ocrpic()
  394.         {
  395.             string jieguo = "";
  396.             bool[,] picpixel = new bool[49, 20];
  397.             for (int ii = 0; ii < 49; ii++)
  398.             {
  399.                 for (int jj = 0; jj < 20; jj++)
  400.                 {
  401.                     if (bp.GetPixel(ii, jj).GetBrightness() < 0.999)
  402.                     {
  403.                         picpixel[ii, jj] = true;
  404.                     }
  405.                 }
  406.             }
  407.             int[] index = new int[8];
  408.             int indexnum = 0;
  409.             bool black = false;
  410.             for (int ii = 0; ii < 49; ii++)
  411.             {
  412.                 bool haveblack = false;
  413.                 for (int jj = 0; jj < 20; jj++)
  414.                 {
  415.                     if (picpixel[ii, jj])
  416.                     {
  417.                         haveblack = true;
  418.                         break;
  419.                     }
  420.                 }
  421.                 if (haveblack && black == false)
  422.                 {
  423.                     index[indexnum] = ii;
  424.                     indexnum++;
  425.                     black = true;
  426.                 }
  427.                 if (!haveblack && black)
  428.                 {
  429.                     index[indexnum] = ii;
  430.                     indexnum++;
  431.                     black = false;
  432.                 }
  433.             }
  434.             if (indexnum < 7)
  435.             {
  436.                 return jieguo;
  437.             }
  438.             if (indexnum == 7)
  439.             {
  440.                 index[7] = 49;
  441.             }
  442.             //**** 
  443.             for (int ii = 0; ii < 4; ii++)
  444.             {
  445.                 int x1 = index[ii * 2];
  446.                 int x2 = index[ii * 2 + 1];
  447.                 int y1 = 0, y2 = 19;
  448.                 bool mb = false;
  449.                 for (int jj = 0; jj < 20; jj++)
  450.                 {
  451.                     for (int kk = x1; kk < x2; kk++)
  452.                     {
  453.                         if (picpixel[kk, jj])
  454.                         {
  455.                             mb = true;
  456.                             break;
  457.                         }
  458.                     }
  459.                     if (mb)
  460.                     {
  461.                         y1 = jj;
  462.                         break;
  463.                     }
  464.                 }
  465.                 mb = false;
  466.                 for (int jj = 19; jj >= 0; jj--)
  467.                 {
  468.                     for (int kk = x1; kk < x2; kk++)
  469.                     {
  470.                         if (picpixel[kk, jj])
  471.                         {
  472.                             mb = true;
  473.                             break;
  474.                         }
  475.                     }
  476.                     if (mb)
  477.                     {
  478.                         y2 = jj;
  479.                         break;
  480.                     }
  481.                 }
  482.                 //**以上是获取有效区域的范围 
  483.                 for (int jj = 0; jj < 20; jj++)
  484.                 {
  485.                     this.datapic[jj] = 0;
  486.                     this.datapic[jj] = 0;
  487.                 }
  488.                 this.xlpic = (byte)(x2 - x1);
  489.                 //如果字符宽度超过16个像素就不予处理 
  490.                 if (xlpic > 16)
  491.                 {
  492.                     continue;
  493.                 }
  494.                 this.ylpic = (byte)(y2 - y1 + 1);
  495.                 int ys = -1;
  496.                 ushort[] addin = new ushort[] { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 };
  497.                 for (int jj = y1; jj <= y2; jj++)
  498.                 {
  499.                     ys++;
  500.                     int xs = -1;
  501.                     for (int kk = x1; kk < x2; kk++)
  502.                     {
  503.                         xs++;
  504.                         if (picpixel[kk, jj])
  505.                         {
  506.                             this.datapic[ys] = (ushort)(this.datapic[ys] + addin[xs]);
  507.                         }
  508.                     }
  509.                 }
  510.                 jieguo = jieguo + this.getchar();
  511.             }
  512.             return jieguo;
  513.         }
  514.     }
  515. }