这是我转的,但不对,得到的数据不对。 public class QQwry { public string ErrMessage=""; public long StartIp =0; public long EndIp =0; public string Country =""; public string Local =""; public int CountryFlag =0; public long RecordCount=0; private System.IO.FileStream file; private long firstStartIp=0; private long lastStartIp=0; private long endIpOff=0; private long tmpOffSet=0; private void getStartIp(long recNo) { long offSet=firstStartIp + 7 * recNo; byte[] b=new byte[offSet+7]; file.Read(b,Convert.ToInt32(offSet),7); endIpOff = Int64.Parse(((char)b[offSet+4]).ToString()); endIpOff += Int64.Parse(((char)b[offSet+5]).ToString())*256; endIpOff += Int64.Parse(((char)b[offSet+6]).ToString())*256*256; StartIp = Int64.Parse(((char)b[offSet]).ToString()); StartIp += Int64.Parse(((char)b[offSet+1]).ToString())*256; StartIp += Int64.Parse(((char)b[offSet+2]).ToString())*256*256; StartIp += Int64.Parse(((char)b[offSet+3]).ToString())*256*256*256; } private void getEndIp() { byte[] b=new byte[endIpOff+5]; file.Read(b,Convert.ToInt32(endIpOff),5); EndIp = Int64.Parse(((char)b[endIpOff]).ToString()); EndIp += Int64.Parse(((char)b[endIpOff+1]).ToString())*256; EndIp += Int64.Parse(((char)b[endIpOff+2]).ToString())*256*256; EndIp += Int64.Parse(((char)b[endIpOff+3]).ToString())*256*256*256; CountryFlag=Int32.Parse(((char)b[endIpOff+4]).ToString()); } private void getCountry() { switch(CountryFlag) { case 1: break; case 2: break; default: break; } } private string getFlagStr(long offSet) { int flag=0; while(true) { byte[] b=new byte[offSet+1]; file.Read(b,Convert.ToInt32(offSet),1); flag=Int32.Parse(b[offSet].ToString()); if(flag==1 || flag==2) { byte[] b2=new byte[offSet+3]; if(flag==2) { CountryFlag=2; endIpOff=offSet-4; } offSet = Int64.Parse(((char)b2[offSet]).ToString()); offSet += Int64.Parse(((char)b2[offSet+1]).ToString())*256; offSet += Int64.Parse(((char)b2[offSet+2]).ToString())*256*256; } else { break; } } if(offSet<12) return ""; tmpOffSet=offSet; return getStr(); } private string getStr() { string str=""; while(true) { byte[] b=new byte[tmpOffSet+1]; file.Read(b,Convert.ToInt32(tmpOffSet),1); if(Int32.Parse(((char)b[tmpOffSet]).ToString()) == 0) break; str=str + ((char)b[tmpOffSet]).ToString(); tmpOffSet++; } return str; } public bool FoundErr { get { if(ErrMessage!="") return true; else return false; } } public QQwry(string sip,string FilePath) { long ip=Ip2Int(sip); long recNo; try { file=File.Open(FilePath,FileMode.Open); } catch { ErrMessage="打开文件错误!"; return; } byte[] b=new byte[8]; file.Read(b,0,8); firstStartIp=Int64.Parse(b[0].ToString()) + Int64.Parse(b[1].ToString())*256 + Int64.Parse(b[2].ToString())*256*256 + Int64.Parse(b[3].ToString())*256*256*256 ; lastStartIp=Int64.Parse(b[4].ToString()) + Int64.Parse(b[5].ToString())*256 + Int64.Parse(b[6].ToString())*256*256 + Int64.Parse(b[7].ToString())*256*256*256 ; RecordCount=(lastStartIp-firstStartIp) / 7; if(RecordCount<=1) { Country ="无记录"; file.Close(); return; } long rangB=0; long rangE=RecordCount; while(rangB<rangE-1) { recNo=(rangB+rangE)/2; getStartIp(recNo); if(ip==StartIp) { rangB=recNo; break; } if(ip>StartIp) rangB=recNo; else rangE=recNo; } getStartIp(rangB); getEndIp(); if((StartIp<=ip) && (EndIp>=ip)) { getCountry(); } else { Country="未知"; Local=""; } file.Close(); } public long Ip2Int(string sip) { string[] saip=sip.Split(".".ToCharArray(),4); long[] ip=new long[4]; int i=0; for(i=0;i<saip.Length-1;i++) { ip[i]=Int64.Parse(saip[i]); } long nip; nip=ip[0]; nip+=ip[1]*256; nip+=ip[2]*256*256; nip+=ip[3]*256*256*256; return nip; } public string Int2Ip(long nip) { long b1,b2,b3,b4; b1=(nip & 0xff000000) >> 24; if(b1<0) b1+=0x100; b2=(nip & 0x00ff0000) >> 16; if (b2<0) b2+=0x100; b3=(nip & 0x0000ff00)>>8; if (b3<0) b3+=0x100; b4= nip & 0x000000ff; if (b4<0) b4+=0x100; string ip; ip=b1.ToString() + "." + b2.ToString() + "." + b3.ToString() + "." + b3.ToString(); return ip; } }
我转一个delphi的,现在就缺.net的了。各位兄兄努力啊 ============================================================= unit qqwry;
interface
uses Classes,Types,SysUtils,Math,dialogs;
type TQQwry = class public StartIP:DWORD; EndIP:DWORD; Country:string; Local:string; CountryFlag:integer; // 标识 Country位置 // 0x01,随后3字节为Country偏移,没有Local // 0x02,随后3字节为Country偏移,接着是Local // 其他,Country,Local,Local有类似的压缩。可能多重引用。 FirstStartIp:DWORD; LastStartIp:DWORD; EndIpOff:integer; fHandle:integer; datafile:string; //FileLen:integer; constructor Create(dbfile:string);virtual; destructor Destroy;override;
function qqwry(dotip:string):integer;
private function IpToInt(ip:string):DWORD; function IntToIp(ipint:integer):string; function toInt(doint:integer):integer; function GetStartIp(RecNo:integer):DWORD; function GetEndIp():DWORD; function GetStr():string; function getFlagStr(offset:integer):string; procedure getCountry(); end;
implementation
function Tqqwry.IpToInt(ip:string):DWORD; var str:TStringList; begin str:=TStringList.Create; str.CommaText:=stringreplace(ip,'.',' ',[rfReplaceAll]); result:=(StrToInt(str.Strings[0]) * 256*256*256) + (StrToInt(str.Strings[1])*256*256) + (StrToInt(str.Strings[2])*256) + StrToInt(str.Strings[3]); str.Free; end;
function Tqqwry.IntToIp(ipint:integer):string; var b1,b2,b3,b4:integer; begin b1:=(ipint and $ff000000)shr 24; if (b1<0) then b1:=b1+$100; b2:=(ipint and $00ff0000)shr 16; if (b2<0) then b2:=b2+$100; b3:=(ipint and $0000ff00)shr 8; if (b3<0) then b3:=b3+$100; b4:= ipint and $000000ff; if (b4<0) then b4:=b4+$100; result:=inttostr(b1)+'.'+inttostr(b2)+'.'+inttostr(b3)+'.'+inttostr(b4); end;
constructor TQQwry.Create(dbfile:string); begin StartIP:=0; EndIP:=0; CountryFlag:=0; FirstStartIp:=0; LastStartIp:=0; EndIpOff:=0; datafile:='QQWry.Dat'; if(dbfile<>'') then datafile:=dbfile; end;
destructor Tqqwry.Destroy; begin if fhandle<>0 then FileClose(fHandle);
end;
function Tqqwry.toInt(doint:integer):integer; begin result:=doint; if doint<0 then result:=result+256; end;
function Tqqwry.GetStartIp(RecNo:integer):DWORD; var offset:dword; buf:array[0..7]of char; begin offset := FirstStartIp + RecNo * 7 ; fileseek ( fhandle , offset, 0 ) ; fileread ( fhandle,buf,7) ;
function tqqwry.GetEndIp():DWORD; var buf:array[0..4]of char; begin FileSeek(fhandle,endipoff,0); FileRead( fhandle,buf,5); EndIP := toint(ord(buf[0])) + (toint(ord(buf[1]))*256) + (toint(ord(buf[2]))*256*256) + (toint(ord(buf[3]))*256*256*256); CountryFlag := ord ( buf[4] ) ; result:=EndIP ; end;
function tqqwry.GetStr():string; var c:integer; buf:byte; begin result:=''; while true do begin c:=FileRead(fhandle,buf,1); if toint(buf)=0 then break; result:=result+chr(buf); end; end;
function tqqwry.getFlagStr(offset:integer):string; var flag:integer; buf:Byte; buffer:array[0..2]of byte; begin
while true do begin FileSeek(fhandle,offset,0); FileRead(fhandle,buf,1); flag:=toint(buf); if((flag=1)or(flag=2))then begin FileRead(fhandle,buffer,3); if flag=2 then begin CountryFlag := 2 ; EndIpOff := offset - 4 ; end; offset := toint(ord(buffer[0])) + (toint(ord(buffer[1]))*256) + (toint(ord(buffer[2]))* 256*256); end else break; end; if offset<12 then begin result:=''; exit; end; FileSeek(fhandle,offset,0); result:=getstr(); end;
procedure tqqwry.getCountry(); begin case CountryFlag of 1..2:begin Country := getFlagStr (EndIpOff+4) ; if(1 = CountryFlag) then Local := '' else Local := getFlagStr (EndIpOff+8); end; else begin Country := getFlagStr (EndIpOff+4) ;
Local := getFlagStr ( fileseek(fhandle,0,1)) ;//fileseek(fhandle,0,1)获得当前文件指针位置 end; end; end;
function tqqwry.qqwry(dotip:string):integer; var nRet:integer; ip:DWORD; buf:array[0..7]of char; RecintCount,RangB,RangE,RecNo:integer; begin fHandle:=FileOpen(datafile,fmOpenRead);
// showmessage(inttostr(RecintCount)+','+inttostr(LastStartIp)); if (RecintCount <= 1) then begin Country := 'FileDataError'; result:=2 ; exit; end; RangB:= 0; RangE:= RecintCount; while (RangB < RangE-1) do begin RecNo:= floor((RangB + RangE) / 2); getStartIp(RecNo); if ip=StartIp then begin RangB:=Recno; break; end; if ip>StartIp then RangB:=RecNo else RangE:=RecNo;
end;//end of while getStartIp ( RangB ) ; getEndIp ( ) ; if((startip<=ip)and(endip>=ip)) then begin nRet:=0; getCountry(); end else begin nRet:=3; Country:='未知'; Local:=''; end; result:=nRet; end;
{
public string ErrMessage="";
public long StartIp =0;
public long EndIp =0;
public string Country ="";
public string Local ="";
public int CountryFlag =0;
public long RecordCount=0; private System.IO.FileStream file;
private long firstStartIp=0;
private long lastStartIp=0;
private long endIpOff=0;
private long tmpOffSet=0; private void getStartIp(long recNo)
{
long offSet=firstStartIp + 7 * recNo;
byte[] b=new byte[offSet+7];
file.Read(b,Convert.ToInt32(offSet),7);
endIpOff = Int64.Parse(((char)b[offSet+4]).ToString());
endIpOff += Int64.Parse(((char)b[offSet+5]).ToString())*256;
endIpOff += Int64.Parse(((char)b[offSet+6]).ToString())*256*256;
StartIp = Int64.Parse(((char)b[offSet]).ToString());
StartIp += Int64.Parse(((char)b[offSet+1]).ToString())*256;
StartIp += Int64.Parse(((char)b[offSet+2]).ToString())*256*256;
StartIp += Int64.Parse(((char)b[offSet+3]).ToString())*256*256*256;
} private void getEndIp()
{
byte[] b=new byte[endIpOff+5];
file.Read(b,Convert.ToInt32(endIpOff),5);
EndIp = Int64.Parse(((char)b[endIpOff]).ToString());
EndIp += Int64.Parse(((char)b[endIpOff+1]).ToString())*256;
EndIp += Int64.Parse(((char)b[endIpOff+2]).ToString())*256*256;
EndIp += Int64.Parse(((char)b[endIpOff+3]).ToString())*256*256*256;
CountryFlag=Int32.Parse(((char)b[endIpOff+4]).ToString());
} private void getCountry()
{
switch(CountryFlag)
{
case 1:
break;
case 2:
break;
default:
break;
}
} private string getFlagStr(long offSet)
{
int flag=0;
while(true)
{
byte[] b=new byte[offSet+1];
file.Read(b,Convert.ToInt32(offSet),1);
flag=Int32.Parse(b[offSet].ToString());
if(flag==1 || flag==2)
{
byte[] b2=new byte[offSet+3];
if(flag==2)
{
CountryFlag=2;
endIpOff=offSet-4;
}
offSet = Int64.Parse(((char)b2[offSet]).ToString());
offSet += Int64.Parse(((char)b2[offSet+1]).ToString())*256;
offSet += Int64.Parse(((char)b2[offSet+2]).ToString())*256*256;
}
else
{
break;
}
}
if(offSet<12)
return "";
tmpOffSet=offSet;
return getStr();
} private string getStr()
{
string str="";
while(true)
{
byte[] b=new byte[tmpOffSet+1];
file.Read(b,Convert.ToInt32(tmpOffSet),1);
if(Int32.Parse(((char)b[tmpOffSet]).ToString()) == 0)
break;
str=str + ((char)b[tmpOffSet]).ToString();
tmpOffSet++;
}
return str;
} public bool FoundErr
{
get
{
if(ErrMessage!="")
return true;
else
return false;
}
}
public QQwry(string sip,string FilePath)
{
long ip=Ip2Int(sip);
long recNo;
try
{
file=File.Open(FilePath,FileMode.Open);
}
catch
{
ErrMessage="打开文件错误!";
return;
}
byte[] b=new byte[8];
file.Read(b,0,8);
firstStartIp=Int64.Parse(b[0].ToString()) + Int64.Parse(b[1].ToString())*256 + Int64.Parse(b[2].ToString())*256*256 + Int64.Parse(b[3].ToString())*256*256*256 ;
lastStartIp=Int64.Parse(b[4].ToString()) + Int64.Parse(b[5].ToString())*256 + Int64.Parse(b[6].ToString())*256*256 + Int64.Parse(b[7].ToString())*256*256*256 ;
RecordCount=(lastStartIp-firstStartIp) / 7;
if(RecordCount<=1)
{
Country ="无记录";
file.Close();
return;
}
long rangB=0;
long rangE=RecordCount;
while(rangB<rangE-1)
{
recNo=(rangB+rangE)/2;
getStartIp(recNo);
if(ip==StartIp)
{
rangB=recNo;
break;
}
if(ip>StartIp)
rangB=recNo;
else
rangE=recNo;
}
getStartIp(rangB);
getEndIp();
if((StartIp<=ip) && (EndIp>=ip))
{
getCountry(); }
else
{
Country="未知";
Local="";
}
file.Close();
}
public long Ip2Int(string sip)
{
string[] saip=sip.Split(".".ToCharArray(),4);
long[] ip=new long[4];
int i=0;
for(i=0;i<saip.Length-1;i++)
{
ip[i]=Int64.Parse(saip[i]);
}
long nip;
nip=ip[0];
nip+=ip[1]*256;
nip+=ip[2]*256*256;
nip+=ip[3]*256*256*256;
return nip;
}
public string Int2Ip(long nip)
{
long b1,b2,b3,b4;
b1=(nip & 0xff000000) >> 24;
if(b1<0) b1+=0x100;
b2=(nip & 0x00ff0000) >> 16;
if (b2<0) b2+=0x100;
b3=(nip & 0x0000ff00)>>8;
if (b3<0) b3+=0x100;
b4= nip & 0x000000ff;
if (b4<0) b4+=0x100;
string ip;
ip=b1.ToString() + "." + b2.ToString() + "." + b3.ToString() + "." + b3.ToString();
return ip;
}
}
=============================================================
unit qqwry;
interface
uses Classes,Types,SysUtils,Math,dialogs;
type
TQQwry = class
public
StartIP:DWORD;
EndIP:DWORD;
Country:string;
Local:string;
CountryFlag:integer; // 标识 Country位置
// 0x01,随后3字节为Country偏移,没有Local
// 0x02,随后3字节为Country偏移,接着是Local
// 其他,Country,Local,Local有类似的压缩。可能多重引用。
FirstStartIp:DWORD;
LastStartIp:DWORD;
EndIpOff:integer;
fHandle:integer;
datafile:string;
//FileLen:integer;
constructor Create(dbfile:string);virtual;
destructor Destroy;override;
function qqwry(dotip:string):integer;
private
function IpToInt(ip:string):DWORD;
function IntToIp(ipint:integer):string;
function toInt(doint:integer):integer;
function GetStartIp(RecNo:integer):DWORD;
function GetEndIp():DWORD;
function GetStr():string;
function getFlagStr(offset:integer):string;
procedure getCountry();
end;
implementation
function Tqqwry.IpToInt(ip:string):DWORD;
var
str:TStringList;
begin
str:=TStringList.Create;
str.CommaText:=stringreplace(ip,'.',' ',[rfReplaceAll]);
result:=(StrToInt(str.Strings[0]) * 256*256*256)
+ (StrToInt(str.Strings[1])*256*256)
+ (StrToInt(str.Strings[2])*256)
+ StrToInt(str.Strings[3]);
str.Free;
end;
function Tqqwry.IntToIp(ipint:integer):string;
var
b1,b2,b3,b4:integer;
begin
b1:=(ipint and $ff000000)shr 24;
if (b1<0) then b1:=b1+$100;
b2:=(ipint and $00ff0000)shr 16;
if (b2<0) then b2:=b2+$100;
b3:=(ipint and $0000ff00)shr 8;
if (b3<0) then b3:=b3+$100;
b4:= ipint and $000000ff;
if (b4<0) then b4:=b4+$100;
result:=inttostr(b1)+'.'+inttostr(b2)+'.'+inttostr(b3)+'.'+inttostr(b4);
end;
constructor TQQwry.Create(dbfile:string);
begin
StartIP:=0;
EndIP:=0;
CountryFlag:=0;
FirstStartIp:=0;
LastStartIp:=0;
EndIpOff:=0;
datafile:='QQWry.Dat';
if(dbfile<>'') then
datafile:=dbfile;
end;
destructor Tqqwry.Destroy;
begin
if fhandle<>0 then FileClose(fHandle);
end;
function Tqqwry.toInt(doint:integer):integer;
begin
result:=doint;
if doint<0 then result:=result+256;
end;
function Tqqwry.GetStartIp(RecNo:integer):DWORD;
var
offset:dword;
buf:array[0..7]of char;
begin
offset := FirstStartIp + RecNo * 7 ;
fileseek ( fhandle , offset, 0 ) ;
fileread ( fhandle,buf,7) ;
EndIpOff := toint(ord(buf[4]))
+ (toint(ord(buf[5]))*256 )
+ (toint(ord(buf[6]))* 256*256);
StartIP := toint(ord(buf[0]))
+ (toint(ord(buf[1]))*256)
+ (toint(ord(buf[2]))*256*256)
+ (toint(ord(buf[3]))*256*256*256);
result:=StartIP ;
end;
function tqqwry.GetEndIp():DWORD;
var
buf:array[0..4]of char;
begin
FileSeek(fhandle,endipoff,0);
FileRead( fhandle,buf,5);
EndIP := toint(ord(buf[0])) + (toint(ord(buf[1]))*256) + (toint(ord(buf[2]))*256*256) + (toint(ord(buf[3]))*256*256*256);
CountryFlag := ord ( buf[4] ) ;
result:=EndIP ;
end;
function tqqwry.GetStr():string;
var
c:integer;
buf:byte;
begin
result:='';
while true do
begin
c:=FileRead(fhandle,buf,1);
if toint(buf)=0 then break;
result:=result+chr(buf);
end;
end;
function tqqwry.getFlagStr(offset:integer):string;
var
flag:integer;
buf:Byte;
buffer:array[0..2]of byte;
begin
while true do
begin
FileSeek(fhandle,offset,0);
FileRead(fhandle,buf,1);
flag:=toint(buf);
if((flag=1)or(flag=2))then
begin
FileRead(fhandle,buffer,3);
if flag=2 then
begin
CountryFlag := 2 ;
EndIpOff := offset - 4 ;
end;
offset := toint(ord(buffer[0])) + (toint(ord(buffer[1]))*256) + (toint(ord(buffer[2]))* 256*256);
end else break;
end;
if offset<12 then
begin
result:='';
exit;
end;
FileSeek(fhandle,offset,0);
result:=getstr();
end;
procedure tqqwry.getCountry();
begin
case CountryFlag of
1..2:begin
Country := getFlagStr (EndIpOff+4) ;
if(1 = CountryFlag) then
Local := ''
else
Local := getFlagStr (EndIpOff+8);
end;
else
begin
Country := getFlagStr (EndIpOff+4) ;
Local := getFlagStr ( fileseek(fhandle,0,1)) ;//fileseek(fhandle,0,1)获得当前文件指针位置
end;
end;
end;
function tqqwry.qqwry(dotip:string):integer;
var
nRet:integer;
ip:DWORD;
buf:array[0..7]of char;
RecintCount,RangB,RangE,RecNo:integer;
begin
fHandle:=FileOpen(datafile,fmOpenRead);
if fHandle=0 then
begin
showmessage('wrong');
result:=-1;
exit;
end;
//filelen:=fileseek(fhandle,0,2);
ip:= IpToInt ( dotip );
FileSeek(fhandle,0,0);
fileRead(fhandle,buf,8);
FirstStartIp := toint(ord(buf[0])) + ((toint(ord(buf[1])))*256) + (toint(ord(buf[2]))*256*256) + (toint(ord(buf[3]))*256*256*256);
LastStartIp := toint(ord(buf[4])) + (toint(ord(buf[5]))*256) + (toint(ord(buf[6]))*256*256) + (toint(ord(buf[7]))*256*256*256);
RecintCount := floor( ( LastStartIp - FirstStartIp ) / 7);
// showmessage(inttostr(RecintCount)+','+inttostr(LastStartIp));
if (RecintCount <= 1) then
begin
Country := 'FileDataError';
result:=2 ;
exit;
end;
RangB:= 0;
RangE:= RecintCount;
while (RangB < RangE-1) do
begin
RecNo:= floor((RangB + RangE) / 2);
getStartIp(RecNo);
if ip=StartIp then
begin
RangB:=Recno;
break;
end;
if ip>StartIp then
RangB:=RecNo
else
RangE:=RecNo;
end;//end of while
getStartIp ( RangB ) ;
getEndIp ( ) ;
if((startip<=ip)and(endip>=ip)) then
begin
nRet:=0;
getCountry();
end else begin
nRet:=3;
Country:='未知';
Local:='';
end;
result:=nRet;
end;
end.
http://www.cnblogs.com/rexsp/archive/2004/12/27/82740.html