您的位置:首页 > 编程语言 > Delphi

delphi读取纯真IP数据库

2007-02-27 10:47 525 查看
unit IPwry;

interface
uses Classes, Types, SysUtils, Math, dialogs;

type
TIPwry = class
public
StartIP: DWORD;
EndIP: DWORD;
Country, City: string;
Local: string;
CountryFlag: integer; // 标识 Country位置
FirstStartIp: DWORD;
LastStartIp: DWORD;
EndIpOff: integer;
fHandle: integer;
datafile: string;
countryOffset: integer;
isChina: Boolean;
constructor Create(dbfile: string); virtual;
destructor Destroy; override;

function IPwry(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 TIPwry.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 TIPwry.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 TIPwry.Create(dbfile: string);
begin
StartIP := 0;
EndIP := 0;
CountryFlag := 0;
FirstStartIp := 0;
LastStartIp := 0;
EndIpOff := 0;
isChina := false;
datafile := 'QQWry.Dat';
if (dbfile <> '') then
datafile := dbfile;
end;

destructor TIPwry.Destroy;
begin
Country := '';
City := '';
Local := '';
if fHandle <> 0 then
FileClose(fHandle);

end;

function TIPwry.toInt(doint: integer): integer;
begin
result := doint;
if doint < 0 then
result := result + 256;
end;

function TIPwry.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 TIPwry.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 TIPwry.GetStr(): string;
var
buf: byte;
begin
result := '';
while true do
begin
fileread(fHandle, buf, 1);
if toInt(buf) = 0 then
break;
result := result + chr(buf);
end;
end;

function TIPwry.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 TIPwry.getCountry();
const
strprovice = '省';
strCity = '市';
AProvice: array[0..31] of string = ('北京', '上海', '天津', '重庆', '河北', '辽宁',
'山东', '黑龙江', '山西', '吉林', '陕西', '河南', '安徽', '江苏', '湖北', '浙江',
'湖南', '江西', '福建', '台湾', '内蒙古', '甘肃', '宁夏', '四川', '贵州', '云南',
'广西', '广东', '海南', '新疆', '青海', '西藏');
var
i, j: integer;
temStr: string;
begin
Country := getFlagStr(EndIpOff + 4);
i := pos(strprovice, Country);
if i > 0 then //为省 ,但有省字。
begin
temStr := Copy(Country, 0, i + 1); //得到省
City := Copy(Country, i + 2, Length(Country));
i := pos(strCity, City); //得到市 
if i > 0 then
City := Copy(City, 0, i + 1);
if City = '' then
City := '未知地区';
Country := temStr;
isChina := true;
end
else
begin
i := pos(strCity, Country);
if i = 5 then // 直辖市
begin
temStr := Copy(Country, 0, i + 1);
City := Copy(Country, i + 2, Length(Country));
Country := temStr;
City := Country;
isChina := true;
end
else if i > 5 then //为省,但没有省字 。
begin
for j := Low(AProvice) to High(AProvice) do
begin
i := pos(AProvice[j], Country);
if i > 0 then
begin
temStr := Copy(Country, 0, Length(AProvice[j]));
City := Copy(Country, Length(AProvice[j]) + 1, Length(Country));
i := pos(strCity, City); //得到市 
if i > 0 then
City := Copy(City, 0, Length(Country) - Length(temStr));
Country := temStr;
isChina := true;
break;
end;
end;
end;
end;
if (2 <> CountryFlag) then
Local := getFlagStr(fileseek(fHandle, 0, 1)) //fileseek(fhandle,0,1)获得当前文件指针位置
else
Local := getFlagStr(EndIpOff + 8);
for j := 1 to Length(Local) do
begin
if (Local[j] in ['a'..'z', 'A'..'Z', '.']) then
begin
Local := '未知地区';
break;
end;
end;
end;

function TIPwry.IPwry(dotip: string): integer;
var
nRet: integer;
ip: DWORD;
buf: array[0..7] of char;
i, RecintCount, RangB, RangE, RecNo: integer;
begin
for i := Low(buf) to High(buf) do
begin
buf[i] := #0;
end;

fHandle := FileOpen(datafile, fmOpenRead);
if fHandle = 0 then
begin
showmessage('wrong');
result := -1;
exit;
end;
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);
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.

unit u_ip;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IPwry, DB, ADODB, Grids, DBGrids, ComCtrls;

type
TFrm_IP = class(TForm)
Button1: TButton;
Button2: TButton;
ADOConnection1: TADOConnection;
IpQuery: TADOQuery;
DataSource1: TDataSource;
Memo1: TMemo;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
function GetIP(IpStr: string): string;
{ Private declarations }
public
procedure SaveIp;
{ Public declarations }
end;

var
Frm_IP: TFrm_IP;

implementation

{$R *.dfm}

procedure TFrm_IP.Button2Click(Sender: TObject);
begin
Application.Terminate ;
end;

function TFrm_IP.GetIP(IpStr: string): string;
var
i, j, DotCnt: integer;
Num, tempStr, StrIP: string;
Arr: array[1..4] of string;
begin
tempStr := '';
StrIP := '';
DotCnt := 0;
for i := Length(IpStr) downto 1 do
begin
if IpStr[i] = ')' then
Continue;

if IpStr[i] = '(' then
Break;
if not (IpStr[i] in ['0'..'9', '.']) then
begin
Result := '';
Exit;
end
else
begin
if IpStr[i] = '.' then
inc(DotCnt);
tempStr := tempStr + IpStr[i];
end;
end;
for i := Length(tempStr) downto 1 do
begin
StrIP := StrIP + tempStr[i];
end;
tempStr := StrIP;
if DotCnt <> 3 then
begin
Result := '';
Exit;
end;
for j := 1 to 3 do
begin
i := Pos('.', tempStr);
Num := Copy(tempStr, 1, i - 1);
Delete(tempStr, 1, i);
Arr[j] := Num;
end;
Arr[4] := tempStr;
try
DotCnt := 0;
for i := 1 to 4 do
begin
j := StrToInt(Arr[i]);
if ((j >= 0) and (j <= 255)) then
inc(DotCnt);
end;
if (DotCnt = 4) then
Result := StrIP
else
Result := '';
except
end;
end;

procedure TFrm_IP.SaveIp;
var
IPwry: TIPwry;
filepath, IpStr, StrIP, strCountry, StrCity: string;
i: integer;
begin
Memo1.Lines.Clear;
if IpQuery.Active then
IpQuery.Close;
IpQuery.Open;
filepath := ExtractFilePath(Application.ExeName) + 'QQWry.dat';
for i := 0 to IpQuery.RecordCount - 1 do
begin
IpQuery.edit;
StrIP := '未知IP';
strCountry := '未知国家';
StrCity := '未知地区';
IpStr := IpQuery.FieldByName('IPStr').AsString;
if IpStr <> '' then
begin
StrIP := GetIP(IpStr);
if (StrIP <> '') then
begin
IPwry := TIPwry.Create(filepath);
try
if IPwry.IPwry(Trim(StrIP)) = 0 then
begin
strCountry := IPwry.Country;
if IPwry.isChina then
StrCity := IPwry.City
else
StrCity := IPwry.Local;
end;

finally
IPwry.Destroy;
end;
end
else
StrIP := '未知IP';
end;
IpQuery.FieldByName('Groupid').AsString := strCountry;
IpQuery.FieldByName('Parentid').AsString := StrCity;
IpQuery.post;
Memo1.Lines.Add(StrIP + ' - ' + strCountry + ' - ' + StrCity + ' - ' + IntToStr(i));
IpQuery.Next;
end;
IpQuery.Close;

end;

procedure TFrm_IP.Button1Click(Sender: TObject);
begin

SaveIp;
end;

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: