diff --git a/backend/getInfo.php b/backend/getInfo.php index 2db3f85..e36f6fb 100644 --- a/backend/getInfo.php +++ b/backend/getInfo.php @@ -1,8 +1,11 @@ getDetail($ip); $specialIpInfo = getSpecialIpInfo($ip); if (is_string($specialIpInfo)) { $info['ip'] = $ip; @@ -13,6 +16,8 @@ function getIPInfo($ip) { $info['timezone'] = null; $info['loc'] = null; $info['isp'] = $specialIpInfo; + $info['cidr'] = $detail['cidr']; + $info['detail'] = $detail['addr']; } else { $rawIspInfo = getIspInfo($ip); $info['ip'] = $ip; @@ -20,21 +25,25 @@ function getIPInfo($ip) { $info['city'] = $rawIspInfo['city']; $info['region'] = $rawIspInfo['region']; $info['country'] = get_country($rawIspInfo['country'])['en']; + $info['country'] .= "(".get_country($rawIspInfo['country'])['cn'].")"; $info['timezone'] = $rawIspInfo['timezone']; $info['loc'] = $rawIspInfo['loc']; $info['isp'] = getIsp($rawIspInfo); - $info['country'] .= "(".get_country($rawIspInfo['country'])['cn'].")"; + $info['cidr'] = $detail['cidr']; + $info['detail'] = $detail['addr']; } if ($_GET['cli'] == "true") { $cli = "IP: ".$info['ip'].PHP_EOL; - $cli = $cli."AS: ".$info['as'].PHP_EOL; - $cli = $cli."City: ".$info['city'].PHP_EOL; - $cli = $cli."Region: ".$info['region'].PHP_EOL; - $cli = $cli."Country: ".$info['country'].PHP_EOL; - $cli = $cli."Timezone: ".$info['timezone'].PHP_EOL; - $cli = $cli."Location: ".$info['loc'].PHP_EOL; - $cli = $cli."ISP: ".$info['isp'].PHP_EOL; + $cli .= "AS: ".$info['as'].PHP_EOL; + $cli .= "City: ".$info['city'].PHP_EOL; + $cli .= "Region: ".$info['region'].PHP_EOL; + $cli .= "Country: ".$info['country'].PHP_EOL; + $cli .= "Timezone: ".$info['timezone'].PHP_EOL; + $cli .= "Location: ".$info['loc'].PHP_EOL; + $cli .= "ISP: ".$info['isp'].PHP_EOL; + $cli .= "CIDR: ".$info['cidr'].PHP_EOL; + $cli .= "Detail: ".$info['detail'].PHP_EOL; return $cli; } diff --git a/backend/qqwry.dat b/backend/qqwry.dat new file mode 100644 index 0000000..de2efb9 Binary files /dev/null and b/backend/qqwry.dat differ diff --git a/backend/qqwry.php b/backend/qqwry.php new file mode 100644 index 0000000..2cae774 --- /dev/null +++ b/backend/qqwry.php @@ -0,0 +1,150 @@ +fp = 0; + if (($this->fp = fopen(__DIR__.'/qqwry.dat', 'rb')) !== false) { + $this->firstip = $this->getlong(); + $this->lastip = $this->getlong(); + $this->totalip = ($this->lastip - $this->firstip) / 7; + } + } + + public function __destruct() { // 析构函数 + if ($this->fp) { + fclose($this->fp); + } + $this->fp = 0; + } + + public function getDetail($ip) { // 获取IP地址区段及所在位置 + if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { // 判断IP是否有效 + return null; + } + $location = $this->getLocation($ip); + if (!$location) { + return null; + } + $detail['cidr'] = $location['beginip'] . ' - ' . $location['endip']; + $detail['addr'] = $location['country'] . $location['area']; + return $detail; + } + + private function getlong() { // 将读取的4字节转化为长整型数 + return unpack('Vlong', fread($this->fp, 4))['long']; + } + + private function getlong3() { // 将读取的3字节转化为长整型数 + return unpack('Vlong', fread($this->fp, 3) . chr(0))['long']; + } + + private function ip2long($ip) { // 将IP地址转为数字地址 + $ip_arr = explode('.', $ip); + return (16777216 * intval($ip_arr[0])) + (65536 * intval($ip_arr[1])) + (256 * intval($ip_arr[2])) + intval($ip_arr[3]); + } + + private function packip($ip) { // 计算压缩后的IP地址 + return pack('N', intval($this->ip2long($ip))); + } + + private function getstring($data = "") { // 读取字符串 + $char = fread($this->fp, 1); + while (ord($char) > 0) { // 字符串读取到\0结束 + $data .= $char; + $char = fread($this->fp, 1); + } + return $data; + } + + private function getArea() { // 获取地区信息 + $flag = fread($this->fp, 1); // 标志字节 + if (ord($flag) == 0) { // 无区域信息 + return ''; + } else if (ord($flag) == 1 || ord($flag) == 2) { // 区域信息被重定向 + fseek($this->fp, $this->getlong3()); + return $this->getstring(); + } else { // 区域信息未被重定向 + return $this->getstring($flag); + } + } + + private function getLocation($ip) { // 根据IP地址返回地区信息 + $ip = $this->packip($ip); + $l = 0; // 搜索下边界 + $u = $this->totalip; // 搜索上边界 + $findip = $this->lastip; // 若未找到则返回最后一条记录 + + while ($l <= $u) { // 发起查找 + $i = floor(($l + $u) / 2); // 计算二分点 + fseek($this->fp, $this->firstip + $i * 7); + $beginip = strrev(fread($this->fp, 4)); // 获取二分点所在区域的下边界 + if ($ip < $beginip) { // 目标IP小于二分区域的下边界 + $u = $i - 1; // 搜索的上边界缩小到二分点以下 + } else { // 目标IP大于或等于二分区域的下边界 + fseek($this->fp, $this->getlong3()); + $endip = strrev(fread($this->fp, 4)); // 获取二分区域的上边界 + if ($ip > $endip) { // 目标IP大于二分区域的上边界 + $l = $i + 1; // 搜索的下边界缩小到二分点以上 + } else { // 目标IP在二分区域内 + $findip = $this->firstip + $i * 7; + break; + } + } + } + fseek($this->fp, $findip); + $location['beginip'] = long2ip($this->getlong()); // 目标IP所在区域的下边界 + $offset = $this->getlong3(); + fseek($this->fp, $offset); + $location['endip'] = long2ip($this->getlong()); // 目标IP所在区域的上边界 + + //获取目标IP的位置信息 + $byte = fread($this->fp, 1); // 标志字节 + switch (ord($byte)) { + case 1: // 国家和区域信息均被重定向 + $countryOffset = $this->getlong3(); // 重定向地址 + fseek($this->fp, $countryOffset); + $byte = fread($this->fp, 1); // 标志字节 + switch (ord($byte)) { + case 2: // 国家信息被重定向 + fseek($this->fp, $this->getlong3()); + $location['country'] = $this->getstring(); + fseek($this->fp, $countryOffset + 4); + $location['area'] = $this->getArea(); + break; + default: // 国家信息未被重定向 + $location['country'] = $this->getstring($byte); + $location['area'] = $this->getArea(); + break; + } + break; + case 2: // 国家信息被重定向 + fseek($this->fp, $this->getlong3()); + $location['country'] = $this->getstring(); + fseek($this->fp, $offset + 8); + $location['area'] = $this->getArea(); + break; + default: // 国家信息未被重定向 + $location['country'] = $this->getstring($byte); + $location['area'] = $this->getArea(); + break; + } + + // 转为UTF-8编码 + $location['country'] = iconv("GBK", "UTF-8", $location['country']); + $location['area'] = iconv("GBK", "UTF-8", $location['area']); + + // 去除附带信息 + if ($location['country'] == " CZ88.NET" || $location['country'] == "纯真网络") { + $location['country'] = "Unknow"; + } + if ($location['area'] == " CZ88.NET") { + $location['area'] = ""; + } + return $location; + } +} diff --git a/index.html b/index.html index 201dc03..61560e6 100644 --- a/index.html +++ b/index.html @@ -26,6 +26,8 @@ $("#timezone").text(data.timezone); $("#loc").text(data.loc); $("#isp").text(data.isp); + $("#cidr").text(data.cidr); + $("#detail").text(data.detail); }); }); }); @@ -69,6 +71,14 @@