Browse Source

refactor: backend

master
Dnomd343 4 years ago
parent
commit
d9f9aeab38
  1. 35
      backend/country.php
  2. 23
      backend/getCountry.php
  3. 125
      backend/getInfo.php
  4. 71
      backend/ipinfo.php
  5. BIN
      backend/qqwry.dat
  6. 29
      backend/qqwry.php
  7. 96
      backend/queryInfo.php

35
backend/country.php

@ -0,0 +1,35 @@
<?php
// 数据来源:country.db
// 请求方式:getCountry($code)
// 返回格式:
// {
// "code": 国家的2位编码
// "en": 国家英文名称
// "cn": 国家中文名称
// }
class countryDB extends SQLite3 {
function __construct() {
$this->open('country.db'); // 国家地区缩写及代号数据库
}
}
function getCountry($code) { // 根据两位国家代码获取英文与中文全称
if ($code == null) {
return null;
}
$db = new countryDB;
$raw = $db->query('SELECT * FROM main WHERE alpha_2="'.$code.'";')->fetchArray(SQLITE3_ASSOC);
$data['code'] = $code;
if ($raw) {
$data['en'] = $raw['name_en'];
$data['cn'] = $raw['name_cn'];
} else {
$data['en'] = "Unknow";
$data['cn'] = null;
}
return $data;
}
?>

23
backend/getCountry.php

@ -1,23 +0,0 @@
<?php
class countryDB extends SQLite3 {
function __construct() {
$this->open('country.db'); // 国家地区缩写及代号数据库
}
}
function getCountry($code) { // 根据两位国家代码获取英文与中文全称
$db = new countryDB;
if ($code == null) {
return null;
}
$dat = $db->query('SELECT * FROM main WHERE alpha_2="'.$code.'";')->fetchArray(SQLITE3_ASSOC);
if ($dat) {
$name_dat['en'] = $code." - ".$dat['name_en'];
$name_dat['cn'] = $dat['name_cn'];
} else {
$name_dat['en'] = $code." - Unknow";
$name_dat['cn'] = null;
}
return $name_dat;
}

125
backend/getInfo.php

@ -1,125 +0,0 @@
<?php
include("getCountry.php");
include("qqwry.php");
function getIPInfo($ip) {
$qqwry = new QQWry();
$detail = $qqwry->getDetail($ip);
$specialInfo = getSpecialInfo($ip);
if (is_string($specialInfo)) {
$info['ip'] = $ip;
$info['as'] = null;
$info['city'] = null;
$info['region'] = null;
$info['country'] = null;
$info['timezone'] = null;
$info['loc'] = null;
$info['isp'] = $specialInfo;
} else {
$rawIspInfo = getInfo($ip);
$info['ip'] = $ip;
$info['as'] = getAS($rawIspInfo);
$info['city'] = $rawIspInfo['city'];
$info['region'] = $rawIspInfo['region'];
$info['country'] = getCountry($rawIspInfo['country'])['en'];
$info['country'] .= "(".getCountry($rawIspInfo['country'])['cn'].")";
$info['timezone'] = $rawIspInfo['timezone'];
$info['loc'] = $rawIspInfo['loc'];
$info['isp'] = getIsp($rawIspInfo);
}
$info['scope'] = tryCIDR($detail['beginIP'], $detail['endIP']);
$info['detail'] = $detail['dataA'] . $detail['dataB'];
if ($_GET['cli'] == "true") { // 使用命令行模式
$cli = "IP: ".$info['ip'] . 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 .= "Scope: ".$info['scope'] . PHP_EOL;
$cli .= "Detail: ".$info['detail'] . PHP_EOL;
return $cli;
}
header('Content-Type: application/json; charset=utf-8'); // 以JSON格式发送
return json_encode($info);
}
function getSpecialInfo($ip) { // 识别特殊IP地址
if ('::1' === $ip) {
return 'localhost IPv6 access';
}
if (stripos($ip, 'fe80:') === 0) {
return 'link-local IPv6 access';
}
if (strpos($ip, '127.') === 0) {
return 'localhost IPv4 access';
}
if (strpos($ip, '10.') === 0) {
return 'private IPv4 access';
}
if (preg_match('/^172\.(1[6-9]|2\d|3[01])\./', $ip) === 1) {
return 'private IPv4 access';
}
if (strpos($ip, '192.168.') === 0) {
return 'private IPv4 access';
}
if (strpos($ip, '169.254.') === 0) {
return 'link-local IPv4 access';
}
return null;
}
function getInfo($ip) { // 获取IP详细信息
$json = file_get_contents('https://ipinfo.io/' . $ip . '/json');
if (!is_string($json)) {
return null;
}
$data = json_decode($json, true);
if (!is_array($data)) {
return null;
}
return $data;
}
function getIsp($rawIspInfo) { // 提取ISP信息
if (
!is_array($rawIspInfo)
|| !array_key_exists('org', $rawIspInfo)
|| !is_string($rawIspInfo['org'])
|| empty($rawIspInfo['org'])
) {
return 'Unknown ISP';
}
return preg_replace('/AS\\d+\\s/', '', $rawIspInfo['org']);
}
function getAS($rawIspInfo) { // 提取AS信息
if (
!is_array($rawIspInfo)
|| !array_key_exists('org', $rawIspInfo)
|| !is_string($rawIspInfo['org'])
|| empty($rawIspInfo['org'])
) {
return 'Unknown AS';
}
if (preg_match('/AS\\d+\\s/', $rawIspInfo['org'], $as) !== 1) {
return 'Unknown AS';
}
return trim($as['0']);
}
function tryCIDR($beginIP, $endIP) {
$tmp = ip2long($endIP) - ip2long($beginIP) + 1;
if (pow(2, intval(log($tmp, 2))) == $tmp) {
return $beginIP . '/' . (32 - log($tmp, 2));
} else {
return $beginIP . ' - ' . $endIP;
}
}
?>

71
backend/ipinfo.php

@ -0,0 +1,71 @@
<?php
// 数据来源:https://ipinfo.io/$ip/json
// 请求方式:getInfo($ip)
// 返回格式:
// {
// "ip": 请求IP
// "as": AS信息
// "city": 城市
// "region": 行政区
// "country": 国家
// "timezone": 时区
// "loc": 经纬度
// "isp": ISP信息
// }
class IPinfo {
public function getInfo($ip) {
$rawInfo = self::getRawInfo($ip);
$info['ip'] = $ip;
$info['as'] = self::getAS($rawInfo);
$info['city'] = $rawInfo['city'];
$info['region'] = $rawInfo['region'];
$info['country'] = $rawInfo['country'];
$info['timezone'] = $rawInfo['timezone'];
$info['loc'] = $rawInfo['loc'];
$info['isp'] = self::getISP($rawInfo);
return $info;
}
private function getRawInfo($ip) { // 获取IP信息
$json = file_get_contents('https://ipinfo.io/' . $ip . '/json');
if (!is_string($json)) {
return null;
}
$data = json_decode($json, true);
if (!is_array($data)) {
return null;
}
return $data;
}
private function getISP($rawInfo) { // 提取ISP信息
if (
!is_array($rawInfo)
|| !array_key_exists('org', $rawInfo)
|| !is_string($rawInfo['org'])
|| empty($rawInfo['org'])
) {
return 'Unknown ISP';
}
return preg_replace('/AS\\d+\\s/', '', $rawInfo['org']);
}
private function getAS($rawInfo) { // 提取AS信息
if (
!is_array($rawInfo)
|| !array_key_exists('org', $rawInfo)
|| !is_string($rawInfo['org'])
|| empty($rawInfo['org'])
) {
return 'Unknown AS';
}
if (preg_match('/AS\\d+\\s/', $rawInfo['org'], $as) !== 1) {
return 'Unknown AS';
}
return trim($as['0']);
}
}
?>

BIN
backend/qqwry.dat

Binary file not shown.

29
backend/qqwry.php

@ -1,25 +1,36 @@
<?php
// 数据来源:纯真IP数据库 qqwry.dat
// 初始化类:new QQWry($fileName)
// 请求方式:getDetail($ip)
// 返回格式:
// {
// "beginIP": IP段起始点
// "endIP": IP段结束点
// "dataA": 国家名
// "dataB": 地区名
// }
//
// 请求版本:getVersion()
// 返回格式:YYYYMMDD
class QQWry {
private $fp; // 文件指针
private $firstRecord; // 第一条记录的偏移地址
private $lastRecord; // 最后一条记录的偏移地址
private $recordNum; // 总记录条数
public function __construct() { // 构造函数
$this->fp = 0;
if (($this->fp = fopen(__DIR__ . '/qqwry.dat', 'rb')) !== false) {
$this->firstRecord = $this->read4byte();
$this->lastRecord = $this->read4byte();
$this->recordNum = ($this->lastRecord - $this->firstRecord) / 7; // 每条索引长度为7字节
}
public function __construct($fileName) { // 构造函数
$this->fp = fopen($fileName, 'rb');
$this->firstRecord = $this->read4byte();
$this->lastRecord = $this->read4byte();
$this->recordNum = ($this->lastRecord - $this->firstRecord) / 7; // 每条索引长度为7字节
}
public function __destruct() { // 析构函数
if ($this->fp) {
fclose($this->fp);
}
$this->fp = 0;
}
private function read4byte() { // 读取4字节并转为long
@ -151,3 +162,5 @@ class QQWry {
}
}
}
?>

96
backend/queryInfo.php

@ -1,14 +1,100 @@
<?php
include("getInfo.php");
include("country.php");
include("qqwry.php");
include("ipinfo.php");
$ip = $_GET['ip'];
function getIPInfo($ip) {
$qqwry = new QQWry('qqwry.dat');
$detail = $qqwry->getDetail($ip);
$specialInfo = checkSpecial($ip);
if (is_string($specialInfo)) {
$info['ip'] = $ip;
$info['as'] = null;
$info['city'] = null;
$info['region'] = null;
$info['country'] = null;
$info['timezone'] = null;
$info['loc'] = null;
$info['isp'] = $specialInfo;
} else {
$data = IPinfo::getInfo($ip);
$country = getCountry($data['country']);
$info['ip'] = $data['ip'];
$info['as'] = $data['as'];
$info['city'] = $data['city'];
$info['region'] = $data['region'];
$info['country'] = $data['country'] . ' - ' . $country['en'];
$info['country'] .= "(" . $country['cn'] . ")";
$info['timezone'] = $data['timezone'];
$info['loc'] = $data['loc'];
$info['isp'] = $data['isp'];
}
$info['scope'] = tryCIDR($detail['beginIP'], $detail['endIP']);
$info['detail'] = $detail['dataA'] . $detail['dataB'];
if (!filter_var($ip, \FILTER_VALIDATE_IP)) {
echo "Illegal IP format".PHP_EOL;
exit;
if ($_GET['cli'] == "true") { // 使用命令行模式
$cli = "IP: ".$info['ip'] . 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 .= "Scope: ".$info['scope'] . PHP_EOL;
$cli .= "Detail: ".$info['detail'] . PHP_EOL;
return $cli;
}
header('Content-Type: application/json; charset=utf-8'); // 以JSON格式发送
return json_encode($info);
}
function checkSpecial($ip) { // 检查特殊IP地址并返回说明
if ('::1' === $ip) {
return 'localhost IPv6 access';
}
if (stripos($ip, 'fe80:') === 0) {
return 'link-local IPv6 access';
}
if (strpos($ip, '127.') === 0) {
return 'localhost IPv4 access';
}
if (strpos($ip, '10.') === 0) {
return 'private IPv4 access';
}
if (preg_match('/^172\.(1[6-9]|2\d|3[01])\./', $ip) === 1) {
return 'private IPv4 access';
}
if (strpos($ip, '192.168.') === 0) {
return 'private IPv4 access';
}
if (strpos($ip, '169.254.') === 0) {
return 'link-local IPv4 access';
}
return null;
}
function tryCIDR($beginIP, $endIP) { // 给定IP范围,尝试计算CIDR
$tmp = ip2long($endIP) - ip2long($beginIP) + 1;
if (pow(2, intval(log($tmp, 2))) == $tmp) { // 判断是否为2的整数次方
return $beginIP . '/' . (32 - log($tmp, 2));
} else {
return $beginIP . ' - ' . $endIP;
}
}
function main() {
$ip = $_GET['ip'];
if (!filter_var($ip, \FILTER_VALIDATE_IP)) {
echo "Illegal IP format".PHP_EOL;
exit;
}
echo getIPInfo($ip);
}
echo getIPInfo($ip);
main();
?>

Loading…
Cancel
Save