순수 IP 데이터베이스 분석 Delphi D10.1 일반 사용
1 unit Net.IPLocation;
2
3 interface
4
5 uses System.Classes, System.SysUtils, Winapi.WinSock, Vcl.Forms,
6 System.Math, System.SyncObjs;
7
8 type
9 TIPLocation = class(TObject)
10 private
11 QQWryFileName: string;
12 QQWryFileStream: TBufferedFileStream;
13 QQWryFileSize: Cardinal;
14 IPRecordNum: Cardinal;
15 FirstIPIndexOffset, LastIPIndexOffset: Cardinal;
16 FLock: TCriticalSection;
17
18 function GetQQWryFileName: string;
19 function GetQQWryFileSize: Cardinal;
20 function GetIPRecordNum: Cardinal;
21 function GetQQWryDate: TDate;
22 function GetQQWryDataFrom: string;
23 function GetIPLocation(IPLocationOffset: Cardinal): TStringlist;
24 function GetIPMsg(IPRecordID: Cardinal): TStringlist;
25 function GetIPRecordID(IP: string): Cardinal;
26 function GetIPValue(IP: string): Cardinal;
27 public
28 constructor Create(cQQWryFileName: string);
29 destructor Destroy; override;
30 function GetLocation(IP: string): String;
31 end;
32
33 function IPLocation: TIPLocation;
34
35 implementation
36
37 var
38 __IPLocation: TIPLocation;
39
40 function IPLocation: TIPLocation;
41 begin
42 if __IPLocation = nil then
43 __IPLocation := TIPLocation.Create(ExtractFilePath(ParamStr(0)) +
44 'qqwry.dat');
45
46 Result := __IPLocation;
47 end;
48
49 { TIPLocation }
50
51 constructor TIPLocation.Create(cQQWryFileName: string);
52 begin
53 inherited Create;
54 FLock := TCriticalSection.Create;
55 QQWryFileName := cQQWryFileName;
56 QQWryFileStream := TBufferedFileStream.Create(QQWryFileName,
57 fmOpenRead or fmShareDenyWrite, 0);
58 QQWryFileSize := QQWryFileStream.Size;
59 QQWryFileStream.Read(FirstIPIndexOffset, 4);
60 QQWryFileStream.Read(LastIPIndexOffset, 4);
61 IPRecordNum := (LastIPIndexOffset - FirstIPIndexOffset) div 7 + 1;
62 end;
63
64 destructor TIPLocation.Destroy;
65 begin
66
67 QQWryFileStream.Free;
68 FLock.Free;
69 inherited Destroy;
70 end;
71
72 function TIPLocation.GetIPLocation(IPLocationOffset: Cardinal): TStringlist;
73 const
74 //
75 REDIRECT_MODE_1 = 1;
76 REDIRECT_MODE_2 = 2;
77 var
78 RedirectMode: byte;
79 CountryFirstOffset, CountrySecondOffset: Cardinal;
80 CountryMsg, AreaMsg: string;
81 //
82 function ReadString(StringOffset: Cardinal): ansistring;
83 var
84 ReadByte: ansichar;
85 begin
86 Result := '';
87 QQWryFileStream.Seek(StringOffset, soFromBeginning);
88 QQWryFileStream.Read(ReadByte, 1);
89 while ord(ReadByte) <> 0 do
90 begin
91 Result := Result + ReadByte;
92 QQWryFileStream.Read(ReadByte, 1);
93 end;
94 end;
95 //
96 function ReadArea(AreaOffset: Cardinal): ansistring;
97 var
98 ModeByte: byte;
99 ReadAreaOffset: Cardinal;
100 begin
101 ReadAreaOffset := 0;
102 QQWryFileStream.Seek(AreaOffset, soFromBeginning);
103 QQWryFileStream.Read(ModeByte, 1);
104 if (ModeByte = REDIRECT_MODE_1) or (ModeByte = REDIRECT_MODE_2) then
105 begin
106 QQWryFileStream.Read(ReadAreaOffset, 3);
107 if ReadAreaOffset = 0 then
108 Result := ' '
109 else
110 Result := ReadString(ReadAreaOffset);
111 end
112 else
113 begin
114 Result := ReadString(AreaOffset);
115 end;
116 end;
117
118 begin
119 CountryFirstOffset := 0;
120 CountrySecondOffset := 0;
121 // 4 , 4 IP IP IP
122 QQWryFileStream.Seek(IPLocationOffset + 4, soFromBeginning);
123 //
124 QQWryFileStream.Read(RedirectMode, 1);
125 // 1
126 if RedirectMode = REDIRECT_MODE_1 then
127 begin
128 // 1, 3
129 QQWryFileStream.ReadData(CountryFirstOffset, 3);
130 //
131 QQWryFileStream.Seek(CountryFirstOffset, soFromBeginning);
132 //
133 QQWryFileStream.Read(RedirectMode, 1);
134 // 2
135 if RedirectMode = REDIRECT_MODE_2 then
136 begin
137 // 3
138 QQWryFileStream.ReadData(CountrySecondOffset, 3);
139 // ,
140 CountryMsg := ReadString(CountrySecondOffset);
141 // 1, 2,
142 //
143 QQWryFileStream.Seek(CountryFirstOffset + 4, soFromBeginning);
144 // 2
145 end
146 else
147 begin
148 CountryMsg := ReadString(CountryFirstOffset);
149 end;
150 // 1
151 AreaMsg := ReadArea(QQWryFileStream.Position);
152 // 2
153 end
154 else if RedirectMode = REDIRECT_MODE_2 then
155 begin
156 QQWryFileStream.ReadData(CountrySecondOffset, 3);
157 CountryMsg := ReadString(CountrySecondOffset);
158 AreaMsg := ReadArea(IPLocationOffset + 8);
159 // , IP
160 end
161 else
162 begin
163 CountryMsg := ReadString(QQWryFileStream.Position - 1);
164 AreaMsg := ReadArea(QQWryFileStream.Position);
165 end;
166 Result := TStringlist.Create;
167 Result.Add(CountryMsg);
168 Result.Add(AreaMsg);
169 end;
170
171 function TIPLocation.GetIPMsg(IPRecordID: Cardinal): TStringlist;
172 var
173 aryStartIP: array [1 .. 4] of byte;
174 strStartIP: string;
175 EndIPOffset: Cardinal;
176 aryEndIP: array [1 .. 4] of byte;
177 strEndIP: string;
178 i: integer;
179 begin
180 EndIPOffset := 0;
181
182 // ID
183 QQWryFileStream.Seek(FirstIPIndexOffset + (IPRecordID - 1) * 7,
184 soFromBeginning);
185 // 4 IP
186 QQWryFileStream.Read(aryStartIP, 4);
187 // 3
188 // QQWryFileStream.Read(EndIPOffset, 3);
189 QQWryFileStream.ReadData(EndIPOffset, 3);
190 //
191 QQWryFileStream.Seek(EndIPOffset, soFromBeginning);
192 // 4 IP
193 QQWryFileStream.Read(aryEndIP, 4);
194
195 // IP
196 strStartIP := '';
197 for i := 4 downto 1 do
198 begin
199 if i <> 1 then
200 strStartIP := strStartIP + IntToStr(aryStartIP[i]) + '.'
201 else
202 strStartIP := strStartIP + IntToStr(aryStartIP[i]);
203 end;
204 strEndIP := '';
205 for i := 4 downto 1 do
206 begin
207 if i <> 1 then
208 strEndIP := strEndIP + IntToStr(aryEndIP[i]) + '.'
209 else
210 strEndIP := strEndIP + IntToStr(aryEndIP[i]);
211 end;
212 Result := TStringlist.Create;
213 Result.Add(strStartIP);
214 Result.Add(strEndIP);
215 // IP
216 // :① ② IP ③ IP
217 Result.AddStrings(GetIPLocation(EndIPOffset));
218 end;
219
220 function TIPLocation.GetIPRecordID(IP: string): Cardinal;
221 function SearchIPRecordID(IPRecordFrom, IPRecordTo, IPValue: Cardinal)
222 : Cardinal;
223 var
224 CompareIPValue1, CompareIPValue2: Cardinal;
225 begin
226 Result := 0;
227 CompareIPValue1 := 0;
228 CompareIPValue2 := 0;
229 QQWryFileStream.Seek(FirstIPIndexOffset + ((IPRecordTo - IPRecordFrom) div 2
230 + IPRecordFrom - 1) * 7, soFromBeginning);
231 QQWryFileStream.Read(CompareIPValue1, 4);
232 QQWryFileStream.Seek(FirstIPIndexOffset + ((IPRecordTo - IPRecordFrom) div 2
233 + IPRecordFrom) * 7, soFromBeginning);
234 QQWryFileStream.Read(CompareIPValue2, 4);
235 //
236 if (IPValue >= CompareIPValue1) and (IPValue < CompareIPValue2) then
237 begin
238 Result := (IPRecordTo - IPRecordFrom) div 2 + IPRecordFrom;
239 end
240 else
241 //
242 if IPValue > CompareIPValue1 then
243 begin
244 Result := SearchIPRecordID((IPRecordTo - IPRecordFrom) div 2 +
245 IPRecordFrom + 1, IPRecordTo, IPValue);
246 end
247 else
248 //
249 if IPValue < CompareIPValue1 then
250 begin
251 Result := SearchIPRecordID(IPRecordFrom, (IPRecordTo - IPRecordFrom)
252 div 2 + IPRecordFrom - 1, IPValue);
253 end;
254 end;
255
256 begin
257 Result := SearchIPRecordID(1, GetIPRecordNum, GetIPValue(IP));
258 end;
259
260 function TIPLocation.GetIPRecordNum: Cardinal;
261 begin
262 Result := IPRecordNum;
263 end;
264
265 function TIPLocation.GetIPValue(IP: string): Cardinal;
266 var
267 tsIP: TStringlist;
268 i: integer;
269 function SplitStringToStringlist(aString: string; aSplitChar: string)
270 : TStringlist;
271 begin
272 Result := TStringlist.Create;
273 while pos(aSplitChar, aString) > 0 do
274 begin
275 Result.Add(copy(aString, 1, pos(aSplitChar, aString) - 1));
276 aString := copy(aString, pos(aSplitChar, aString) + 1,
277 length(aString) - pos(aSplitChar, aString));
278 end;
279 Result.Add(aString);
280 end;
281
282 begin
283 tsIP := SplitStringToStringlist(IP, '.');
284 Result := 0;
285 for i := 3 downto 0 do
286 begin
287 Result := Result + StrToInt(tsIP[i]) * trunc(power(256, 3 - i));
288 end;
289 end;
290
291 function TIPLocation.GetLocation(IP: string): String;
292 begin
293 FLock.Enter;
294 try
295 Result := GetIPMsg(GetIPRecordID(IP))[2];
296 finally
297 FLock.Leave;
298 end;
299 end;
300
301 function TIPLocation.GetQQWryDataFrom: string;
302 begin
303 Result := GetIPMsg(GetIPRecordNum)[2];
304 end;
305
306 function TIPLocation.GetQQWryDate: TDate;
307 var
308 DateString: string;
309 begin
310 DateString := GetIPMsg(GetIPRecordNum)[3];
311 DateString := copy(DateString, 1, pos('IP ', DateString) - 1);
312 DateString := StringReplace(DateString, ' ', '-',
313 [rfReplaceAll, rfIgnoreCase]);
314 DateString := StringReplace(DateString, ' ', '-',
315 [rfReplaceAll, rfIgnoreCase]);
316 DateString := StringReplace(DateString, ' ', '-',
317 [rfReplaceAll, rfIgnoreCase]);
318 Result := StrToDate(DateString);
319 end;
320
321 function TIPLocation.GetQQWryFileName: string;
322 begin
323 Result := QQWryFileName;
324 end;
325
326 function TIPLocation.GetQQWryFileSize: Cardinal;
327 begin
328 Result := QQWryFileSize;
329 end;
330
331 initialization
332
333 finalization
334
335 if __IPLocation <> nil then
336 __IPLocation.Free;
337
338 end.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.