如何实现评论区显示IP地址归属地功能

622 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

最近各大平台相续推出IP归属地显示功能,我有个朋友也做个评论显示IP地址归属地的功能。

原理介绍

IP地址本身是不具备定位功能的,IP地址只是用来决定一台网络主机在网络里的相对位置,这个位置是相对而言,可以通过IP路由到目的主机,并不会关心目的主机的物理位置在哪里。所以理论上是不可能定位到IP地址的物理位置的。所以只能另辟蹊径了。

image.png IP是全球统一的,具有全球唯一性,为了保证唯一性要统一做分配,需要IP都去这个统一分配系统申请,但有缺陷,这个统一系统肯定忙得要死。所以将这个分配的权力下放,将一批IP分配给某一个组织,这个组织再进行进一步分配给下一级组织……。谁拿走了这批IP地址需要进行登记,登记的时候随便做个组织地址的登记,咦,暴露了物理地址。所以就可以通过这个登记的信息去获取这批IP地址的大概位置。比如某组织申请了IP地址为1.4.127.0-1.4.127.255,通过查询登记信息,发现这个组织在广东,那么如果某一个IP在这个批IP地址范围里面那么就能知道这个IP归属地是广东。

image.png 但是如果一个公司,具备遍布全国的内网,但访问外网的时候统一都使用总公司的IP访问,那么最终,这个公司所有人上网呈现的IP属地,都会是总公司的属地。这意味着,IP属地是从外网第一跳开始计算的,如果公司存在庞大的内网,那么内网中的具体地址,并不会体现到外网访问中。这就导致通过登记地址的方式进行判断IP的归属地仍然是存在一定问题的。

虽然IP本身不具备定位功能,但是使用IP的主机具备定位功能,比如某APP获取定位信息的同时获取IP信息,然后一起上传到服务器保存起来,这样就可以实时的获取IP地址的真实物理位置,就可以不断完善和修改IP地址的物理位置信息库了。这种方式需要APP使用量达到一个规模才能得到比较准确的位置信息,比如地图类APP就能有这个能力。

分析

通过上面可知,IP的归属地信息可以通过登记组织位置获取并通过不断的获取使用IP的设备位置信息完善更正位置信息库。
同时也知道IP的位置信息范围越大更新频次越低,比如只是定位到国家那么几乎不更新,但是定位到县级甚至乡级那么可能随时会更新的。比如手机通过移动网络连接到互联网,移动网络会分配一个内网IP给手机,手机和互联网上主机进行通讯使用的是公网IP是当前手机所连接网络所属的移动分公司的的公网IP,移动分公司所又有是一组IP池,动态的分配给通过给该子公司网络连接互联网的设备。一般运营商公网IP是按区域分配,具体分配策略就不太懂了。不过可以知道肯定会先根据省份分配。所以IP归属地精确到省份级别的更新的频率是非常低的。

image.png 当然可以在评论发表的时候获取用户设备的GPS位置信息会更加准确。

实现

一、call api boy

最舒服的当然是调别人的接口啦,有问题还可以甩锅给别人。

收钱但是靠谱点的使用个地图厂商的接口
百度地图接口
高德地图接口

也可以白嫖免费的
这里
这里
这里

二、crud boy

调别人接口舒服但是要么收钱要么不好用,当然自己做的更好。但是自己做的要维护地址和IP的关系太难了,如果使用的场景只是定位到省份,并且存在一点误差也能接受的,比如评论带归属地功能的场景。

image.png
由上文分析知道,定位到省份区域的更新频率是非常低,所以可以去找别人整理好的IP和物理地址对应关系数据或者通过脚本从某个网站爬出来,存到本地之后每次查询即可,因为更新频率低所以久不久更新一下即可。

优化

IPv4地址就有2^32个地址,不能每次都遍历吧,所以可以将其排序后使用二分法进行快速查找,并且IP分配给某一个区域时一般是一批次一批次的分配的,所以连续的一个批次属于相同的归属地,所以使用范围保存可以进一步减少所使用的空间。下面举个例子
将按照如下格式保存起来,其中前两位byte为数据头,记录版本号、数据的编码方式、所以字节数、数据长度范围、索引的长度等信息。之后就是索引数据,根据主键进行有序排列的,并且保存索引对应数据的位置。这样当查询时直接通过二分法直接查询到索引的位置后拿到数据的位置,之后取出数据即可。
号码归属地查询也是类似的方法,号码也是有类似的规律,前7位为号段,比如1300000这个号段山东省济南市的,所以拿到一个号码通过号段即可查询到归属地。甚至可以查到是哪个运营商,但是因为可以允许携号转网了,所以运营商更新快估计不准了。

image.png

image.png

优化后IPv4定位源数据仅仅3M多一点,国内IP定位到省级,国外定位到国家级别。

源码在这
gitee.com/eedui/locat…
github.com/eedui/locat…

不装了,我是借鉴这个项目的
gitee.com/lionsoul/ip…
github.com/lionsoul201…