用QQWry.Dat作数据源实现IP地址检索[C#]
2024-07-21 02:18:26
供稿:网友
前几天有一个朋友说一直想有一个这样程序,可以把网络上比较流行的qqwry.dat作为ip数据源来实现ip地址的查询显示。可是网络上一直没有出现.net的版本。我想既然如此,那我就抽空写一写好了,先到google上go了一下,找到相关介绍文章,了解了其格式,然后又参考了其它语言版本的程序,一天多一点时间,终于把这个东西写好了。不敢独享,帖出来 /**//******************************************************************
** file name:ipscaner.cs
** copyright (c) 2004-2005 pptech studio(pptech.net)
** creater:rexsp(msn:[email protected])
** create date:2004-12-27 20:10:28
** modifier:
** modify date:
** description:to scan the ip location from qqwry.dat
** version: ipscaner 1.0.0
******************************************************************/
using system;
using system.io;
using system.collections;
using system.text;
using system.text.regularexpressions;
namespace pptech.website.businessrules
{
/**//// <summary>
/// to scan the ip location from qqwry.dat
/// </summary>
public class ipscaner
{
私有成员#region 私有成员
private string datapath;
private string ip;
private string country;
private string local;
private long firststartip=0;
private long laststartip=0;
private filestream objfs = null;
private long startip=0;
private long endip=0;
private int countryflag=0;
private long endipoff=0;
private string errmsg=null;
#endregion
构造函数#region 构造函数
public ipscaner()
{
//
// todo: 在此处添加构造函数逻辑
//
}
#endregion
公共属性#region 公共属性
public string datapath
{
set{datapath=value;}
}
public string ip
{
set{ip=value;}
}
public string country
{
get{return country;}
}
public string local
{
get{return local;}
}
public string errmsg
{
get{return errmsg;}
}
#endregion
搜索匹配数据#region 搜索匹配数据
private int qqwry()
{
string pattern = @"(((/d{1,2})|(1/d{2})|(2[0-4]/d)|(25[0-5]))/.){3}((/d{1,2})|(1/d{2})|(2[0-4]/d)|(25[0-5]))";
regex objre = new regex(pattern);
match objma = objre.match(ip);
if(!objma.success)
{
this.errmsg="ip格式错误";
return 4;
}
long ip_int = this.iptoint(ip);
int nret=0;
if(ip_int>=iptoint("127.0.0.0")&&ip_int<=iptoint("127.255.255.255"))
{
this.country="本机内部环回地址";
this.local="";
nret=1;
}
else if((ip_int>=iptoint("0.0.0.0")&&ip_int<=iptoint("2.255.255.255"))||(ip_int>=iptoint("64.0.0.0")&&ip_int<=iptoint("126.255.255.255"))||(ip_int>=iptoint("58.0.0.0")&&ip_int<=iptoint("60.255.255.255")))
{
this.country="网络保留地址";
this.local="";
nret=1;
}
objfs = new filestream(this.datapath, filemode.open, fileaccess.read);
try
{
//objfs.seek(0,seekorigin.begin);
objfs.position=0;
byte[] buff = new byte[8] ;
objfs.read(buff,0,8);
firststartip=buff[0]+buff[1]*256+buff[2]*256*256+buff[3]*256*256*256;
laststartip=buff[4]*1+buff[5]*256+buff[6]*256*256+buff[7]*256*256*256;
long recordcount=convert.toint64((laststartip-firststartip)/7.0);
if(recordcount<=1)
{
country="filedataerror";
objfs.close();
return 2;
}
long range=recordcount;
long rangb=0;
long recno=0;
while(rangb<range-1)
{
recno=(range+rangb)/2;
this.getstartip(recno);
if(ip_int==this.startip)
{
rangb = recno;
break;
}
if(ip_int>this.startip)
rangb=recno;
else
range=recno;
}
this.getstartip(rangb);
this.getendip();
if(this.startip<=ip_int&&this.endip>=ip_int)
{
this.getcountry();
this.local=this.local.replace("(我们一定要解放台湾!!!)","");
}
else
{
nret=3;
this.country="未知";
this.local="";
}
objfs.close();
return nret;
}
catch
{
return 1;
}
}
#endregion
ip地址转换成int数据#region ip地址转换成int数据
private long iptoint(string ip)
{
char[] dot = new char[]{'.'};
string [] iparr = ip.split(dot);
if(iparr.length==3)
ip=ip+".0";
iparr=ip.split(dot);
long ip_int=0;
long p1=long.parse(iparr[0])*256*256*256;
long p2=long.parse(iparr[1])*256*256;
long p3=long.parse(iparr[2])*256;
long p4=long.parse(iparr[3]);
ip_int=p1+p2+p3+p4;
return ip_int;
}
#endregion
int转换成ip#region int转换成ip
private string inttoip(long ip_int)
{
long seg1=(ip_int&0xff000000)>>24;
if(seg1<0)
seg1+=0x100;
long seg2=(ip_int&0x00ff0000)>>16;
if(seg2<0)
seg2+=0x100;
long seg3=(ip_int&0x0000ff00)>>8;
if(seg3<0)
seg3+=0x100;
long seg4=(ip_int&0x000000ff);
if(seg4<0)
seg4+=0x100;
string ip=seg1.tostring()+"."+seg2.tostring()+"."+seg3.tostring()+"."+seg4.tostring();
return ip;
}
#endregion
获取起始ip范围#region 获取起始ip范围
private long getstartip(long recno)
{
long offset = firststartip+recno*7;
//objfs.seek(offset,seekorigin.begin);
objfs.position=offset;
byte [] buff = new byte[7];
objfs.read(buff,0,7);
endipoff=convert.toint64(buff[4].tostring())+convert.toint64(buff[5].tostring())*256+convert.toint64(buff[6].tostring())*256*256;
startip=convert.toint64(buff[0].tostring())+convert.toint64(buff[1].tostring())*256+convert.toint64(buff[2].tostring())*256*256+convert.toint64(buff[3].tostring())*256*256*256;
return startip;
}
#endregion
获取结束ip#region 获取结束ip
private long getendip()
{
//objfs.seek(endipoff,seekorigin.begin);
objfs.position=endipoff;
byte [] buff = new byte[5];
objfs.read(buff,0,5);
this.endip=convert.toint64(buff[0].tostring())+convert.toint64(buff[1].tostring())*256+convert.toint64(buff[2].tostring())*256*256+convert.toint64(buff[3].tostring())*256*256*256;
this.countryflag=buff[4];
return this.endip;
}
#endregion
获取国家/区域偏移量#region 获取国家/区域偏移量
private string getcountry()
{
switch(this.countryflag)
{
case 1:
case 2:
this.country=getflagstr(this.endipoff+4);
this.local=( 1 == this.countryflag )?" ":this.getflagstr(this.endipoff+8);
break;
default:
this.country=this.getflagstr(this.endipoff+4);
this.local=this.getflagstr(objfs.position);
break;
}
return " ";
}
#endregion
获取国家/区域字符串#region 获取国家/区域字符串
private string getflagstr(long offset)
{
int flag=0;
byte [] buff = new byte[3];
while(1==1)
{
//objfs.seek(offset,seekorigin.begin);
objfs.position=offset;
flag = objfs.readbyte();
if(flag==1||flag==2)
{
objfs.read(buff,0,3);
if(flag==2)
{
this.countryflag=2;
this.endipoff=offset-4;
}
offset=convert.toint64(buff[0].tostring())+convert.toint64(buff[1].tostring())*256+convert.toint64(buff[2].tostring())*256*256;
}
else
{
break;
}
}
if(offset<12)
return " ";
objfs.position=offset;
return getstr();
}
#endregion
getstr#region getstr
private string getstr()
{
byte lowc=0;
byte upc=0;
string str="";
byte[] buff = new byte[2];
while(1==1)
{
lowc= (byte)objfs.readbyte();
if(lowc==0)
break;
if(lowc>127)
{
upc=(byte)objfs.readbyte();
buff[0]=lowc;
buff[1]=upc;
system.text.encoding enc = system.text.encoding.getencoding("gb2312");
str+=enc.getstring(buff);
}
else
{
str+=(char)lowc;
}
}
return str;
}
#endregion
获取ip地址#region 获取ip地址
public string iplocation()
{
this.qqwry();
return this.country+this.local;
}
public string iplocation(string datapath,string ip)
{
this.datapath=datapath;
this.ip=ip;
this.qqwry();
return this.country+this.local;
}
#endregion
}
}
调用方式:
测试地址搜索#region 测试地址搜索
ipscaner objscan = new ipscaner();
string ip="221.224.205.13";
[email protected]"e:/个人资料/imtools/qqwryupdate/qqwry.dat";
objscan.ip=ip;
string addre=objscan.iplocation();
string err=objscan.errmsg;
#endregion