forked from 17mon/quxianku
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Ipx.quxian.php
95 lines (74 loc) · 2.63 KB
/
Ipx.quxian.php
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
<?php
/* 区县级 IP 地址库查询类 by pAUL gAO <[email protected]> */
class IPX_Quxian
{
private static $ip = NULL;
private static $fp = NULL;
private static $offset = NULL;
private static $index = NULL;
public function __destruct()
{
if (self::$fp !== NULL)
{
fclose(self::$fp);
}
}
private static function init()
{
if (self::$fp === NULL)
{
self::$ip = new self();
self::$fp = fopen(__DIR__ . '/quxian.datx', 'rb');
if (self::$fp === FALSE)
{
return 'Invalid IP Quxian file';
}
self::$offset = unpack('Nlen', fread(self::$fp, 4));
if (self::$offset['len'] < 4)
{
return 'Invalid IP Quxian file';
}
self::$index = fread(self::$fp, self::$offset['len'] - 4);
}
}
public static function find($ip)
{
$nip = gethostbyname($ip);
$ipdot = explode('.', $nip);
$ipdot[0] = (int)$ipdot[0];
if (self::$fp === NULL)
{
self::init();
}
$nip = pack('N', ip2long($nip));
$tmp_offset = $ipdot[0] * 256 + intval($ipdot[1]);
$tmp_offset = $tmp_offset * 4;
$start = unpack('Vlen', self::$index[$tmp_offset] . self::$index[$tmp_offset + 1] . self::$index[$tmp_offset + 2] . self::$index[$tmp_offset + 3]);
$index_offset = $index_length = [];
$loop = 0;
for ($start = $start['len'] * 13 + 262144; $start < self::$offset['len'] - 262148; $start += 13)
{
if ((self::$index{$start} . self::$index{$start + 1} . self::$index{$start + 2} . self::$index{$start + 3}) <= $nip)
{
$loop++;
if ($nip <= (self::$index{$start + 4} . self::$index{$start + 5} . self::$index{$start + 6} . self::$index{$start + 7}))
{
$index_offset = unpack('Vlen', self::$index{$start + 8} . self::$index{$start + 9} . self::$index{$start + 10} . self::$index[$start + 11]);
$index_length = unpack('Clen', self::$index{$start + 12});
break;
}
}
else
{
break;
}
}
if ($index_offset === [])
{
return FALSE;
}
fseek(self::$fp, self::$offset['len'] + $index_offset['len'] - 262144);
return explode("\t", fread(self::$fp, $index_length['len']));
}
}
?>