QQ验证码识别(版本较旧,思路才是王道)

2019-04-15 14:44发布

QQ验证码识别源代码(C#/NET1.1) using System; namespace QQ { /// /// yzm 的摘要说明。 /// public class yzm { public yzm(public System.Drawing.Bitmap pic) { this.bp = pic; } /// /// 将一个int值存入到4个字节的字节数组(从高地址开始转换,最高地址的值以无符号整型参与"与运算") /// /// 要处理的int值 /// 存放信息的字符数组 public static void getbytesfromint(int thevalue, byte[] thebuff) { long v1=0; long v2=0; long v3=0; long v4=0; uint b1=(uint)4278190080; uint b2=(uint)16711680; uint b3=(uint)65280; uint b4=(uint)255; v1=thevalue & b1; v2=thevalue & b2; v3=thevalue & b3; v4=thevalue & b4; thebuff[0]=(byte)(v1>>24); thebuff[1]=(byte)(v2>>16); thebuff[2]=(byte)(v3>>8); thebuff[3]=(byte)v4; } /// /// 将一个ushort值存入到2个字节的字节数组(从高地址开始转换,最高地址的值以无符号整型参与"与运算") /// /// 要处理的ushort值 /// 存放信息的字符数组 public static void getbytesfromushort(ushort thevalue, byte[] thebuff) { ushort v1=0; ushort v2=0; ushort b1=(ushort)65280; ushort b2=(ushort)255; v1=(ushort)(thevalue & b1); v2=(ushort)(thevalue & b2); thebuff[0]=(byte)(v1>>8); thebuff[1]=(byte)(v2); } /// /// 将4个字节的字节数组转换成一个int值 /// /// 字符数组 /// public static int getintfrombyte(byte[] thebuff) { int jieguo=0; long mid=0; long m1=0; long m2=0; long m3=0; long m4=0; m1=(thebuff[0]<<24); m2=(thebuff[1]<<16); m3=(thebuff[2]<<8); m4=thebuff[3]; mid=m1+m2+m3+m4; jieguo=(int)mid; return jieguo; } /// /// 将2个字节的字节数组转换成一个ushort值 /// /// 字符数组 /// public static ushort getushortfrombyte(byte[] thebuff) { int jieguo1=0; jieguo1=(thebuff[0]<<8)+thebuff[1]; ushort jieguo=(ushort)jieguo1; return jieguo; } /// /// 将内存中的数据写入硬盘(保存特征库) /// /// 保存的位置 public static void writetofile(string thefile) { System.IO.FileStream fs = new System.IO.FileStream(thefile,System.IO.FileMode.OpenOrCreate,System.IO.FileAccess.ReadWrite); byte[] buff0=new byte[4]; getbytesfromint(datanum,buff0); fs.Write(buff0,0,4); for(int ii=0;ii /// 从文件中读取信息,并保存在内存中相应的位置 /// /// 特征库文件 public static void readfromfile(string thefile) { int allnum=0; byte[] buff=new byte[4]; System.IO.FileStream fs = new System.IO.FileStream(thefile,System.IO.FileMode.Open,System.IO.FileAccess.Read); fs.Read(buff,0,4); allnum=getintfrombyte(buff); byte[] buff0=new byte[2]; for(int ii=0;ii /// 验证码图片 /// public System.Drawing.Bitmap bp =new System.Drawing.Bitmap(49,20); /// /// 特征库的长度 /// public static int datanum=0; /// /// 特征库数据 /// public static ushort[,] datap=new ushort[100000,20]; /// /// 长度与高度 /// public static byte[,] dataxy=new byte[100000,2]; /// /// 对应的字符 /// public static byte[] datachar=new byte[100000]; /// /// 等待处理的数据 /// public ushort[] datapic=new ushort[20]; /// /// 有效长度 /// public byte xlpic=0; /// /// 有效宽度 /// public byte ylpic=0; /// /// 检索特征库中存在的记录 /// public string getchar() { //如果查找不到,就返回空串 string jieguo=""; for(int ii=0;ii /// 检查特征库中是否已经存在相关记录 /// bool ischardatain() { bool jieguo=false; for(int ii=0;ii1 || System.Math.Abs(dataxy[ii,1]-ylpic)>1) { continue; } for(int jj=0;jj<20;jj++) { if(datap[ii,jj]!=datapic[jj]) { notsamenum++; } } if(notsamenum<4) { string asdasd=((char)datachar[ii]).ToString(); return true; } } return jieguo; } /// /// 添加到特征库中,并暂时将对应的字符置为空格以待人工识别 /// void adddatawithnullchar() { if(this.ischardatain()) { return; } for(int ii=0;ii<20;ii++) { datap[datanum,ii]=this.datapic[ii]; } //暂时将对应的字符置为空格以待人工识别 datachar[datanum]=32; dataxy[datanum,0]=this.xlpic; dataxy[datanum,1]=this.ylpic; datanum++; } /// /// 检查验证码图片是否能分成4个部分,如果可以就检查4个字符在特征库中是否已经存在,如果不存在, /// 就添加到特征库中,并暂时将对应的字符置为空格以待人工识别 /// public void writetodata() { bool[,] picpixel=new bool[49,20]; for(int ii=0;ii<49;ii++) { for(int jj=0;jj<20;jj++) { if(bp.GetPixel(ii,jj).GetBrightness()<0.999) { picpixel[ii,jj]=true; } } } int[] index=new int[8]; int indexnum=0; bool black=false; for(int ii=0;ii<49;ii++) { bool haveblack=false; for(int jj=0;jj<20;jj++) { if(picpixel[ii,jj]) { haveblack=true; break; } } if(haveblack && black==false) { index[indexnum]=ii; indexnum++; black=true; } if(!haveblack && black) { index[indexnum]=ii; indexnum++; black=false; } } if(indexnum<7) { return; } if(indexnum==7) { index[7]=49; } //**** for(int ii=0;ii<4;ii++) { int x1=index[ii*2]; int x2=index[ii*2+1]; int y1=0,y2=19; bool mb=false; for(int jj=0;jj<20;jj++) { for(int kk=x1;kk=0;jj--) { for(int kk=x1;kk16) { continue; } this.ylpic=(byte)(y2-y1+1); int ys=-1; ushort[] addin=new ushort[]{1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768}; for(int jj=y1;jj<=y2;jj++) { ys++; int xs=-1; for(int kk=x1;kk /// 识别图片 /// /// 返回识别结果(如果返回的字符串长度小于4就说明识别失败) public string ocrpic() { string jieguo=""; bool[,] picpixel=new bool[49,20]; for(int ii=0;ii<49;ii++) { for(int jj=0;jj<20;jj++) { if(bp.GetPixel(ii,jj).GetBrightness()<0.999) { picpixel[ii,jj]=true; } } } int[] index=new int[8]; int indexnum=0; bool black=false; for(int ii=0;ii<49;ii++) { bool haveblack=false; for(int jj=0;jj<20;jj++) { if(picpixel[ii,jj]) { haveblack=true; break; } } if(haveblack && black==false) { index[indexnum]=ii; indexnum++; black=true; } if(!haveblack && black) { index[indexnum]=ii; indexnum++; black=false; } } if(indexnum<7) { return jieguo; } if(indexnum==7) { index[7]=49; } //**** for(int ii=0;ii<4;ii++) { int x1=index[ii*2]; int x2=index[ii*2+1]; int y1=0,y2=19; bool mb=false; for(int jj=0;jj<20;jj++) { for(int kk=x1;kk=0;jj--) { for(int kk=x1;kk16) { continue; } this.ylpic=(byte)(y2-y1+1); int ys=-1; ushort[] addin=new ushort[]{1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768}; for(int jj=y1;jj<=y2;jj++) { ys++; int xs=-1; for(int kk=x1;kk