├── .github └── workflows │ └── php.yml ├── .gitignore ├── LICENSE ├── README.MD ├── UPDATE.MD ├── bin ├── update-ip.php └── update-region-code.php ├── composer.json ├── doc ├── README.md ├── introduction-ipdb.txt ├── introduction-qqwry.txt └── qqwry.pdf ├── src ├── IpLocation.php ├── IpParser │ ├── IpParserInterface.php │ ├── IpV6wry.php │ └── QQwry.php ├── StringParser.php └── libs │ ├── ipv6wry.db │ └── qqwry.dat ├── tests └── ip.php └── tmp └── mca_region_code.html /.github/workflows/php.yml: -------------------------------------------------------------------------------- 1 | name: PHP Composer 2 | 3 | on: 4 | push: 5 | branches: [ 2.x, 3.x ] 6 | pull_request: 7 | branches: [ 2.x, 3.x] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | 17 | - name: Validate composer.json and composer.lock 18 | run: composer validate --strict 19 | 20 | - name: Cache Composer packages 21 | id: composer-cache 22 | uses: actions/cache@v2 23 | with: 24 | path: vendor 25 | key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} 26 | restore-keys: | 27 | ${{ runner.os }}-php- 28 | 29 | - name: Install dependencies 30 | run: composer install --prefer-dist --no-progress 31 | 32 | # Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit" 33 | # Docs: https://getcomposer.org/doc/articles/scripts.md 34 | 35 | # - name: Run test suite 36 | # run: composer run-script test 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .DS_Store 3 | vendor 4 | composer.lock -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | 21 | ============================================================ 22 | 23 | 本协议是用户(您)和ZX公司(zxinc.org)之间关于使用ZX IP地址数据库(本数据库)达成的协议。您安装或者使用本数据库的行为将视为对本协的接受及同意。除非您接受本协议,否则请勿下载、安装或使用本数据库,并请将本数据库从计算机中移除。 24 | 25 | 1. 本数据库是免费许可软件,不进行出售。你可以免费的复制,分发和传播本数据库,但您必须保证每一份复制、分发和传播都必须是未更改过的,完整和真实的。 26 | 2. 您作为个人使用本数据库。您只能对本数据库进行非商业性的应用。 27 | 3. 任何免费软件以及非商业性网站均可无偿使用本数据库,但在其说明上均应注明本数据库的名称和来源为“ZX IP地址数据库”。 28 | 4. 本数据库为免费共享软件。我们对本数据库产品不提供任何保证,不对任何用户因本数据库所遭遇到的任何理论上的或实际上的损失承担责任,不对用户使用本数据库造成的任何后果承担责任。 29 | 5. 本数据库所收集的信息,均是从网上收集而来。数据库只包含IP与其对应的地址,但是这些数据不会涉及您的个人信息,因此也不会侵害您的隐私。 30 | 6. 欢迎任何人为我们提供正确详尽的IP地址。可登录网站(http://ip.zxinc.org)或论坛(http://bbs.zxinc.org)提交正确的IP与地址,以便我们修正并提高本数据库IP地址数据的准确性。 31 | 32 | ZX公司(zxinc.org)版权所有,保留一切解释权利 ! 33 | 34 | 35 | ============================================================ 36 | 37 | QQ IP数据库 纯真版 38 | 39 | IP数据记录:527250条 40 | 数据库大小:9M 41 | 42 | 收集了包括中国电信、中国移动、中国联通、长城宽带、聚友宽带等 ISP 的 IP 地址数据,包括网吧数据。 43 | 希望能够通过大家的共同努力打造一个没有未知数据,没有错误数据的QQ IP。IP数据库每5天更新一次,请大家 44 | 定期更新IP数据库! 45 | 因为IP地址数据是民间收集的,各运营商也会不时的更改IP段,所以有点遗漏、错误是难免的。随数据库附 46 | 送IP解压,查询软件。假如发现IP地址有不对的,或想提供新的IP地址,请到纯真IP小秘书提供IP地址数据,或者登陆 47 | 纯真时空论坛“电脑板块”中的“代理及IP板”块告诉我们。,以便及时更新IP数据库。谢谢! 48 | 49 | ★★★★★★★★★★★★★★★★★★★★★★★★ 50 | 在线升级数据库: 51 | 随数据库附送的查询程序(ip.exe)具有在线检测并升级IP数据库的功能,只要运行该程序,点击右上角的 52 | “在线升级”,就可以升级IP数据库到新的版本,无需再到下载网站下载新版的IP数据库。 53 | ★★★★★★★★★★★★★★★★★★★★★★★★ 54 | 55 | 56 | IP小秘书:http://www.cz88.net/ip 57 | 纯真网络:http://www.cz88.net 58 | 纯真时空论坛:http://bbs.cz88.net 59 | 60 | 金狐 QQ:486126 EMail:admin@cz88.net 61 | 62 | 63 | ============================================================ 64 | 65 | ip-database 协议简述 66 | 67 | 1,可以自由使用解析程序,但务必在程序内标明来源。https://github.com/itbdw/it-database 68 | 2,不保证任何准确性,应当知晓方可使用 69 | 3,仅供学习和娱乐用,如被用作违法事宜,本人均不承担任何责任 70 | 4,其它合理性解释权利归本人所有 71 | 72 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 这套识别程序的数据库是免费IP数据库、IP离线地址库。支持将IP转化为结构化的国家、省、市、县、运营商、地区信息 4 | 5 | 0,该系统是离线的,代码内已经包含IPV4+IPV6离线包。 6 | 7 | 1,IPV4数据库基于纯真IP库,IP地址纠错相关和最新地址获取请直接去纯真官网,具体见最下方链接。IPV6数据库见最下方链接。 8 | 9 | 2,纯真IP识别算法来源网络。 10 | 11 | 3,结构化程序来自我2012年的脑洞。 12 | 13 | 纯真IP数据存储时,并不是结构化的,因此 结构化程序 解析出来有误差在所难免,国内 ip 可以识别出省份,基本可以识别出市。运营商、县数据看运气。 14 | 15 | ## 使用说明 16 | 17 | 当前版本为3.x(ipv4+ipv6),如需要2.x请访问 https://github.com/itbdw/ip-database/tree/2.x 18 | 19 | 目前3.x无缝兼容2.x版本,理论上可直接升级。 20 | 21 | ``` 22 | composer require 'itbdw/ip-database' ^3.0 23 | ``` 24 | 25 | 26 | ```php 27 | 28 | //根据实际情况,基本上用框架(如 Laravel)的话不需要手动引入 29 | //require 'vendor/autoload.php'; 30 | 31 | use itbdw\Ip\IpLocation; 32 | 33 | //0配置使用 34 | echo json_encode(IpLocation::getLocation($ip), JSON_UNESCAPED_UNICODE) . "\n"; 35 | 36 | //支持自定义文件路径 37 | $qqwry_filepath = '/abspath/qqwry.dat'; 38 | $ipv6wry_path = '/abspath/ipv6wry.db'; 39 | echo json_encode(IpLocation::getLocation($ip, $qqwry_filepath), JSON_UNESCAPED_UNICODE) . "\n"; 40 | 41 | 42 | ``` 43 | 44 | ## 响应 45 | 46 | 获取成功 47 | ```json 48 | { 49 | "ip": "163.177.65.160", 50 | "country": "中国", 51 | "province": "广东", 52 | "city": "深圳市", 53 | "county": "", 54 | "isp": "联通", 55 | "area": "中国广东省深圳市腾讯计算机系统联通节点" 56 | } 57 | ``` 58 | 59 | 异常 60 | ```json 61 | { 62 | "error": "ip invalid" 63 | } 64 | ``` 65 | 66 | 67 | ## 本地测试测试 68 | 69 | ``` 70 | cd 进入 ip-database 目录 ,composer install 71 | 72 | php tests/ip.php 73 | 74 | {"ip":"172.217.25.14","country":"美国","province":"","city":"","county":"","area":"美国 Google全球边缘网络","isp":""} 75 | {"ip":"140.205.172.5","country":"中国","province":"上海","city":"","county":"","area":"中国上海 阿里云","isp":""} 76 | {"ip":"123.125.115.110","country":"中国","province":"北京","city":"","county":"","area":"中国北京 北京百度网讯科技有限公司联通节点(BGP)","isp":"联通"} 77 | {"ip":"221.196.0.0","country":"中国","province":"天津","city":"河北区","county":"","area":"中国天津河北区 联通","isp":"联通"} 78 | {"ip":"60.195.153.98","country":"中国","province":"北京","city":"顺义区","county":"","area":"中国北京顺义区 后沙峪金龙网吧","isp":""} 79 | {"ip":"218.193.183.35","country":"中国","province":"上海","city":"","county":"","area":"中国上海 D27-707","isp":""} 80 | {"ip":"210.74.2.227","country":"中国","province":"北京","city":"","county":"","area":"中国北京 实验学院机房","isp":""} 81 | {"ip":"162.105.217.0","country":"中国","province":"北京","city":"","county":"","area":"中国北京 4区-4f","isp":""} 82 | {"ip":"fe80:0000:0001:0000:0440:44ff:1233:5678","country":"局域网","province":"","city":"","county":"","area":"局域网 本地链路单播地址","isp":""} 83 | {"ip":"2409:8900:103f:14f:d7e:cd36:11af:be83","country":"中国","province":"北京","city":"","county":"","area":"中国北京 中国移动CMNET网络","isp":"移动"} 84 | 85 | php tests/ip.php -i 58.196.128.0 86 | {"ip":"58.196.128.0","country":"中国","province":"上海","city":"","county":"","area":"中国上海 上海交通大学","isp":""} 87 | 88 | php tests/ip.php -i 2409:8a00:6c1d:81c0:51b4:d603:57d1:b5ec 89 | {"ip":"2409:8a00:6c1d:81c0:51b4:d603:57d1:b5ec","country":"中国","province":"北京","city":"","county":"","area":"中国北京 中国移动公众宽带","isp":"移动"} 90 | 91 | ``` 92 | 93 | ## 提高下载速度 94 | 建议腾讯云加速 https://mirrors.cloud.tencent.com/help/composer.html 95 | 96 | 原因 https://github.com/itbdw/ip-database/issues/42 97 | 98 | ## 赞助喝口水 99 | 这个项目也是多个日夜思考的结果,如果觉得对你有帮助,小手一抖也是感谢的。 100 |
75 | * $result 是返回的数组
76 | * $result['ip'] 输入的ip
77 | * $result['country'] 国家 如 中国
78 | * $result['area'] 最完整的信息 如 中国河北省邢台市威县新科网吧(北外街)
79 | *
80 | *
81 | * @param $ip
82 | * @return array
83 | */
84 | public function getAddr($ip)
85 | {
86 | $filename = $this->filePath;
87 | if (!file_exists($filename)) {
88 | trigger_error("Failed open ip database file!");
89 | throw new \Exception('Failed open ip database');
90 | }
91 | if (is_null($this->fp)) {
92 | $this->fp = 0;
93 | if (($this->fp = fopen($filename, 'rb')) !== false) {
94 | $this->firstIp = $this->getLong();
95 | $this->lastIp = $this->getLong();
96 | $this->totalIp = ($this->lastIp - $this->firstIp) / 7;
97 | }
98 | }
99 | $location = $this->getLocation($ip);
100 | return $location;
101 | }
102 |
103 | /**
104 | * 返回读取的长整型数
105 | *
106 | * @access private
107 | * @return int
108 | */
109 | private function getLong()
110 | {
111 | //将读取的little-endian编码的4个字节转化为长整型数
112 | $result = unpack('Vlong', fread($this->fp, 4));
113 | return $result['long'];
114 | }
115 |
116 | /**
117 | * 根据所给 IP 地址或域名返回所在地区信息
118 | *
119 | * @access public
120 | * @param string $ip
121 | * @return array ip country area beginip endip
122 | */
123 | private function getLocation($ip)
124 | {
125 | if (!$this->fp) {
126 | return null;
127 | }
128 | // 如果数据文件没有被正确打开,则直接返回空
129 | $location['ip'] = $ip;
130 | $ip = $this->packIp($location['ip']);
131 | // 将输入的IP地址转化为可比较的IP地址
132 | // 不合法的IP地址会被转化为255.255.255.255
133 | // 对分搜索
134 | $l = 0;
135 | // 搜索的下边界
136 | $u = $this->totalIp;
137 | // 搜索的上边界
138 | $findip = $this->lastIp;
139 | // 如果没有找到就返回最后一条IP记录(qqwry.dat的版本信息)
140 | while ($l <= $u) {
141 | // 当上边界小于下边界时,查找失败
142 | $i = floor(($l + $u) / 2);
143 | // 计算近似中间记录
144 | fseek($this->fp, $this->firstIp + $i * 7);
145 | $beginip = strrev(fread($this->fp, 4));
146 | // 获取中间记录的开始IP地址
147 | // strrev函数在这里的作用是将little-endian的压缩IP地址转化为big-endian的格式
148 | // 以便用于比较,后面相同。
149 | if ($ip < $beginip) {
150 | // 用户的IP小于中间记录的开始IP地址时
151 | $u = $i - 1;
152 | // 将搜索的上边界修改为中间记录减一
153 | } else {
154 | fseek($this->fp, $this->getLong3());
155 | $endip = strrev(fread($this->fp, 4));
156 | // 获取中间记录的结束IP地址
157 | if ($ip > $endip) {
158 | // 用户的IP大于中间记录的结束IP地址时
159 | $l = $i + 1;
160 | // 将搜索的下边界修改为中间记录加一
161 | } else {
162 | // 用户的IP在中间记录的IP范围内时
163 | $findip = $this->firstIp + $i * 7;
164 | break;
165 | // 则表示找到结果,退出循环
166 | }
167 | }
168 | }
169 | //获取查找到的IP地理位置信息
170 | fseek($this->fp, $findip);
171 | $location['beginip'] = long2ip($this->getLong());
172 | // 用户IP所在范围的开始地址
173 | $offset = $this->getLong3();
174 | fseek($this->fp, $offset);
175 | $location['endip'] = long2ip($this->getLong());
176 | // 用户IP所在范围的结束地址
177 | $byte = fread($this->fp, 1);
178 | // 标志字节
179 | switch (ord($byte)) {
180 | case 1: // 标志字节为1,表示国家和区域信息都被同时重定向
181 | $countryOffset = $this->getLong3();
182 | // 重定向地址
183 | fseek($this->fp, $countryOffset);
184 | $byte = fread($this->fp, 1);
185 | // 标志字节
186 | switch (ord($byte)) {
187 | case 2: // 标志字节为2,表示国家信息被重定向
188 | fseek($this->fp, $this->getLong3());
189 | $location['country'] = $this->getString();
190 | fseek($this->fp, $countryOffset + 4);
191 | $location['area'] = $this->getArea();
192 | break;
193 | default: // 否则,表示国家信息没有被重定向
194 | $location['country'] = $this->getString($byte);
195 | $location['area'] = $this->getArea();
196 | break;
197 | }
198 | break;
199 | case 2: // 标志字节为2,表示国家信息被重定向
200 | fseek($this->fp, $this->getLong3());
201 | $location['country'] = $this->getString();
202 | fseek($this->fp, $offset + 8);
203 | $location['area'] = $this->getArea();
204 | break;
205 | default: // 否则,表示国家信息没有被重定向
206 | $location['country'] = $this->getString($byte);
207 | $location['area'] = $this->getArea();
208 | break;
209 | }
210 | $location['country'] = iconv("GBK", "UTF-8", $location['country']);
211 | $location['area'] = iconv("GBK", "UTF-8", $location['area']);
212 | if ($location['country'] == " CZ88.NET" || $location['country'] == "纯真网络") {
213 | // CZ88.NET表示没有有效信息
214 | $location['country'] = "无数据";
215 | }
216 | if ($location['area'] == " CZ88.NET") {
217 | $location['area'] = "";
218 | }
219 | return $location;
220 | }
221 |
222 | /**
223 | * 返回压缩后可进行比较的IP地址
224 | *
225 | * @access private
226 | * @param string $ip
227 | * @return string
228 | */
229 | private function packIp($ip)
230 | {
231 | // 将IP地址转化为长整型数,如果在PHP5中,IP地址错误,则返回False,
232 | // 这时intval将Flase转化为整数-1,之后压缩成big-endian编码的字符串
233 | return pack('N', intval($this->ip2long($ip)));
234 | }
235 |
236 | /**
237 | * Ip 地址转为数字地址
238 | * php 的 ip2long 这个函数有问题
239 | * 133.205.0.0 ==>> 2244804608
240 | *
241 | * @param string $ip 要转换的 ip 地址
242 | * @return int 转换完成的数字
243 | */
244 | private function ip2long($ip)
245 | {
246 | $ip_arr = explode('.', $ip);
247 | $iplong = (16777216 * intval($ip_arr[0])) + (65536 * intval($ip_arr[1])) + (256 * intval($ip_arr[2])) + intval($ip_arr[3]);
248 | return $iplong;
249 | }
250 |
251 | /**
252 | * 返回读取的3个字节的长整型数
253 | *
254 | * @access private
255 | * @return int
256 | */
257 | private function getLong3()
258 | {
259 | //将读取的little-endian编码的3个字节转化为长整型数
260 | $result = unpack('Vlong', fread($this->fp, 3) . chr(0));
261 | return $result['long'];
262 | }
263 |
264 | /**
265 | * 返回读取的字符串
266 | *
267 | * @access private
268 | * @param string $data
269 | * @return string
270 | */
271 | private function getString($data = "")
272 | {
273 | $char = fread($this->fp, 1);
274 | while (ord($char) > 0) {
275 | // 字符串按照C格式保存,以\0结束
276 | $data .= $char;
277 | // 将读取的字符连接到给定字符串之后
278 | $char = fread($this->fp, 1);
279 | }
280 | return $data;
281 | }
282 |
283 | /**
284 | * 返回地区信息
285 | *
286 | * @access private
287 | * @return string
288 | */
289 | private function getArea()
290 | {
291 | $byte = fread($this->fp, 1);
292 | // 标志字节
293 | switch (ord($byte)) {
294 | case 0: // 没有区域信息
295 | $area = "";
296 | break;
297 | case 1:
298 | case 2: // 标志字节为1或2,表示区域信息被重定向
299 | fseek($this->fp, $this->getLong3());
300 | $area = $this->getString();
301 | break;
302 | default: // 否则,表示区域信息没有被重定向
303 | $area = $this->getString($byte);
304 | break;
305 | }
306 | return $area;
307 | }
308 |
309 | /**
310 | * 析构函数,用于在页面执行结束后自动关闭打开的文件。
311 | */
312 | public function __destruct()
313 | {
314 | if ($this->fp) {
315 | fclose($this->fp);
316 | }
317 | $this->fp = 0;
318 | }
319 | }
--------------------------------------------------------------------------------
/src/StringParser.php:
--------------------------------------------------------------------------------
1 | $value) {
148 |
149 | if (false !== strpos($location['country'], $value)) {
150 | $isChina = true;
151 | $location['province'] = $value;
152 |
153 | //直辖市
154 | if (in_array($value, self::$dictCityDirectly)) {
155 |
156 | //直辖市
157 | $_tmp_province = explode($value, $location['country']);
158 |
159 | //市辖区
160 | if (isset($_tmp_province[1])) {
161 |
162 | $_tmp_province[1] = self::lTrim($_tmp_province[1], $separatorCity);
163 |
164 |
165 | if (strpos($_tmp_province[1], $separatorDistrict) !== false) {
166 | $_tmp_qu = explode($separatorDistrict, $_tmp_province[1]);
167 |
168 | //解决 休息休息校区 变成城市区域
169 | $isHitBlackTail = false;
170 | foreach (self::$dictDistrictBlackTails as $blackTail) {
171 | //尾
172 | if (mb_substr($_tmp_qu[0], -mb_strlen($blackTail)) == $blackTail) {
173 | $isHitBlackTail = true;
174 | break;
175 | }
176 | }
177 |
178 | //校区,学区
179 | if ((!$isHitBlackTail) && mb_strlen($_tmp_qu[0]) < 5) {
180 | //有点尴尬
181 | $location['city'] = $_tmp_qu[0] . $separatorDistrict;
182 | }
183 | }
184 | }
185 | } else {
186 |
187 | //没有省份标志 只能替换
188 | $_tmp_city = str_replace($location['province'], '', $location['country']);
189 |
190 | //防止直辖市捣乱 上海市xxx区 =》 市xx区
191 | $_tmp_city = self::lTrim($_tmp_city, $separatorCity);
192 |
193 | //内蒙古 类型的 获取市县信息
194 | if (strpos($_tmp_city, $separatorCity) !== false) {
195 | //市
196 | $_tmp_city = explode($separatorCity, $_tmp_city);
197 |
198 | $location['city'] = $_tmp_city[0] . $separatorCity;
199 |
200 | //县
201 | if (isset($_tmp_city[1])) {
202 | if (strpos($_tmp_city[1], $separatorCounty) !== false) {
203 | $_tmp_county = explode($separatorCounty, $_tmp_city[1]);
204 | $location['county'] = $_tmp_county[0] . $separatorCounty;
205 | }
206 |
207 | //区
208 | if (!$location['county'] && strpos($_tmp_city[1], $separatorDistrict) !== false) {
209 | $_tmp_qu = explode($separatorDistrict, $_tmp_city[1]);
210 | $location['county'] = $_tmp_qu[0] . $separatorDistrict;
211 | }
212 | }
213 | }
214 | }
215 |
216 | break;
217 | }
218 | }
219 | }
220 |
221 | if ($isChina) {
222 | $location['country'] = '中国';
223 | }
224 |
225 |
226 | $result['ip'] = $location['ip'];
227 |
228 | $result['country'] = $location['country'];
229 | $result['province'] = $location['province'];
230 | $result['city'] = $location['city'];
231 | $result['county'] = $location['county'];
232 |
233 | $result['area'] = $location['country'] . $location['province'] . $location['city'] . $location['county'] . ' ' . $location['org_area'];
234 |
235 | $result['isp'] = self::getIsp($result['area']);
236 |
237 | if ($withOriginal) {
238 | $result['org'] = $org;
239 | }
240 |
241 | return $result;
242 | }
243 |
244 |
245 | /**
246 | * @param $str
247 | * @return string
248 | */
249 | private static function getIsp($str)
250 | {
251 | $ret = '';
252 |
253 | foreach (self::$dictIsp as $k => $v) {
254 | if (false !== strpos($str, $v)) {
255 | $ret = $v;
256 | break;
257 | }
258 | }
259 |
260 | return $ret;
261 | }
262 |
263 | private static function lTrim($word, $w) {
264 | $pos = mb_stripos($word, $w);
265 | if ($pos === 0) {
266 | $word = mb_substr($word, 1);
267 | }
268 | return $word;
269 | }
270 |
271 |
272 | }
--------------------------------------------------------------------------------
/src/libs/ipv6wry.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itbdw/ip-database/977b44904396390272a18cbf7ec29893d602652f/src/libs/ipv6wry.db
--------------------------------------------------------------------------------
/src/libs/qqwry.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itbdw/ip-database/977b44904396390272a18cbf7ec29893d602652f/src/libs/qqwry.dat
--------------------------------------------------------------------------------
/tests/ip.php:
--------------------------------------------------------------------------------
1 |
4 | * @since 2015-06-11
5 | */
6 |
7 | //you do not need to do this if use composer!
8 | //require dirname(__DIR__) . '/src/IpParser/IpParserInterface.php';
9 | //
10 | //require dirname(__DIR__) . '/src/IpLocation.php';
11 | //require dirname(__DIR__) . '/src/IpParser/QQwry.php';
12 | //require dirname(__DIR__) . '/src/IpParser/IpV6wry.php';
13 | //require dirname(__DIR__) . '/src/StringParser.php';
14 |
15 | //需要 composer install 或者去掉上面注释,并注释这一行
16 | include dirname(__DIR__) .'/vendor/autoload.php';
17 |
18 | $input = getopt("i:", [], $id);
19 |
20 | use itbdw\Ip\IpLocation;
21 |
22 | $ips = [
23 | "172.217.25.14",//美国
24 | "140.205.172.5",//杭州
25 | "123.125.115.110",//北京
26 | "221.196.0.0",//
27 | "60.195.153.98",
28 |
29 | //bug ip 都是涉及到直辖市的
30 | "218.193.183.35", //"province":"上海交通大学闵行校区",
31 | "210.74.2.227", //,"province":"北京工业大学","city":"",
32 | "162.105.217.0", //,"province":"北京大学万柳学区","ci
33 |
34 | "fe80:0000:0001:0000:0440:44ff:1233:5678",
35 | "2409:8900:103f:14f:d7e:cd36:11af:be83",
36 | "2400:3200:baba::1",//阿里云
37 |
38 |
39 |
40 | ];
41 |
42 | if (isset($input['i']) || isset($input['ip'])) {
43 | $ips = [];
44 |
45 | if (isset($input['i'])) {
46 | $ips[] = $input['i'];
47 | }
48 |
49 | if (isset($input['ip'])) {
50 | $ips[] = $input['ip'];
51 | }
52 | }
53 |
54 | foreach ($ips as $ip) {
55 | echo json_encode(IpLocation::getLocation($ip), JSON_UNESCAPED_UNICODE) . "\n";
56 | }
57 |
58 |
59 |
--------------------------------------------------------------------------------