-
Notifications
You must be signed in to change notification settings - Fork 0
/
City.au3
101 lines (82 loc) · 3.35 KB
/
City.au3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include-once
#include <WinAPI.au3>
Dim $IPIP_DATA = @ScriptDir&"\mydata4vipday2.datx"
Global Const $HX_REF = "0123456789ABCDEF"
Global Const $iIndexSize = _HexToDecimal(_BinaryMid($IPIP_DATA, 0, 1)&_BinaryMid($IPIP_DATA, 1, 1)&_BinaryMid($IPIP_DATA, 2, 1)&_BinaryMid($IPIP_DATA, 3, 1))
Func FindIP($IP)
Local $iPos = 0
Local $iMid = 0
Local $iLow = 0
Local $iHigh = Int(($iIndexSize - 262144 - 262148) / 9) - 1
Local $iIP = _ip2long($IP)
Local $iPrefix, $iSuffix, $iTmpPos, $iOffset, $iLength, $sData
While $iLow <= $iHigh
$iMid = Int(($iLow + $iHigh) / 2)
$iPos = $iMid * 9 + 262148
$iPrefix = 0
If $iMid > 0 Then
$iTmpPos = ($iMid - 1) * 9 + 262148
$iPrefix = _HexToDecimal(_BinaryMid($IPIP_DATA, ($iTmpPos), 1)&_BinaryMid($IPIP_DATA, ($iTmpPos + 1), 1)&_BinaryMid($IPIP_DATA, ($iTmpPos + 2), 1)&_BinaryMid($IPIP_DATA, ($iTmpPos + 3), 1)) + 1
EndIf
$iSuffix = _HexToDecimal(_BinaryMid($IPIP_DATA, ($iPos), 1)&_BinaryMid($IPIP_DATA, ($iPos + 1), 1)&_BinaryMid($IPIP_DATA, ($iPos + 2), 1)&_BinaryMid($IPIP_DATA, ($iPos + 3), 1))
If $iIP < $iPrefix Then
$iHigh = $iMid - 1
ElseIf $iIP > $iSuffix Then
$iLow = $iMid + 1
Else
$iOffset = _HexToDecimal(_BinaryMid($IPIP_DATA, ($iPos + 6), 1)&_BinaryMid($IPIP_DATA, ($iPos + 5), 1)&_BinaryMid($IPIP_DATA, ($iPos + 4), 1))
$iLength = _HexToDecimal(_BinaryMid($IPIP_DATA, ($iPos + 7), 1)&_BinaryMid($IPIP_DATA, ($iPos + 8), 1))
$iPos = $iOffset - 262144 + $iIndexSize
$sData = BinaryToString(_HexRead($IPIP_DATA, $iPos, $iLength), 4)
Return StringSplit($sData, @TAB, 2)
EndIf
WEnd
EndFunc ;==>FindIP
Func _BinaryMid($FilePath, $Offset, $Length, $Method = "byte")
Return StringTrimLeft(_HexRead($FilePath, $Offset, $Length, $Method), 2)
EndFunc ;==>_BinaryMid
Func _ip2long($IP)
$aSplit = StringSplit($IP, '.')
If $aSplit[0] < 4 Then Return -1
Return ($aSplit[1] * 16777216) + ($aSplit[2] * 65536) + ($aSplit[3] * 256) + ($aSplit[4] * 1)
EndFunc ;==>_ip2long
Func _HexToDecimal($hx_hex)
If StringLeft($hx_hex, 2) = "0x" Then $hx_hex = StringMid($hx_hex, 3)
If StringIsXDigit($hx_hex) = 0 Then Return SetError(1, @error, 0)
Local $ret="", $hx_count=0, $hx_array = StringSplit($hx_hex, ""), $Ii, $hx_tmp
For $Ii = $hx_array[0] To 1 Step -1
$hx_tmp = StringInStr($HX_REF, $hx_array[$Ii]) - 1
$ret += $hx_tmp * 16 ^ $hx_count
$hx_count += 1
Next
Return $ret
EndFunc ;==>_HexToDecimal
Func _HexRead($FilePath, $Offset, $Length)
Local $Buffer, $ptr, $fLen, $hFile, $Result, $Read, $err, $Pos
If Not FileExists($FilePath) Then Return SetError(1, @error, 0)
$fLen = FileGetSize($FilePath)
If $Offset > $fLen Then Return SetError(2, @error, 0)
If $fLen < $Offset + $Length Then Return SetError(3, @error, 0)
$Buffer = DllStructCreate("byte[" & $Length & "]")
$ptr = DllStructGetPtr($Buffer)
$hFile = _WinAPI_CreateFile($FilePath, 2, 2, 0)
If $hFile = 0 Then Return SetError(5, @error, 0)
$Pos = $Offset
$Result = _WinAPI_SetFilePointer($hFile, $Pos)
$err = @error
If $Result = 0xFFFFFFFF Then
_WinAPI_CloseHandle($hFile)
Return SetError(6, $err, 0)
EndIf
$Read = 0
$Result = _WinAPI_ReadFile($hFile, $ptr, $Length, $Read)
$err = @error
If Not $Result Then
_WinAPI_CloseHandle($hFile)
Return SetError(7, $err, 0)
EndIf
_WinAPI_CloseHandle($hFile)
If Not $Result Then Return SetError(8, @error, 0)
$Result = DllStructGetData($Buffer, 1)
Return $Result
EndFunc ;==>_HexRead