网上流传最广的免费IP库,是纯真的IP库:
http://www.cz88.net/,且该库一直有维护,但缺点是不太准确。
淘宝的IP地址库比较准确,且提供了IP查询的接口:
http://ip.taobao.com/。但它没有提供全量下载,且一秒内调用不能超过10次。
于是萌生了一个想法:
以纯真IP库作为IP分段的依据,以此去调用淘宝的接口,从而获得比较准确的IP库。
以纯真IP库的几行记录为例:
a.235995136*14.17.0.0*235997951*14.17.10.255*广东省*深圳市*广东省深圳市*电信
b.3546091247*211.93.14.239*3546091519*211.93.15.255*青海省*西宁市*青海省西宁市*联通
处理方式如下:
1.对于记录a,14.17.0.0和14.17.10.255,分两次调用淘宝的接口,获得结果均为:
14.17.0.0-14.17.10.255 广东省广州市
这种情况最为简单,直接用淘宝的结果替换纯真的结果即可。
2.对于记录b,211.93.14.239和211.93.15.255,分两次调用淘宝的接口,获得结果为:
211.93.14.239 青海省海南藏族自治州
211.93.15.255 青海省西宁市
出现了前后不一致的情况。
这时候怎么办呢?
把211.93.14.239-211.93.15.255这个IP段进行粗略的分段,按IP的前三段相同的,分为一个小段:
211.93.14.239-211.93.14.255 青海省海南藏族自治州
211.93.15.0-211.93.15.255 青海省西宁市
在每一个小段里,前后一致,纯真的一个IP段变成了两个IP段。
但这样做是基于一个前提:那就是认为211.93.15.0-211.93.15.255这样的(x.y.z.0-x.y.z.255,前三部分相同)所有IP是落在同一个城市。
这个前提不一定成立的。因此以此得到的数据,只是相对准确。
那对于x.y.z.0和x.y.z.255,如果落在不同城市呢?
这时候没有更好的办法了,只能遍历x.y.z.0-x.y.z.255之间的所有IP,得到结果后再把城市相同的进行合并。
在我的测试过程中,有455个这样的IP段是前后不一致的。
这样的处理很繁琐,我花费了几天才处理完毕,现在把结果分享出来,供有需要的人下载:
http://pan.baidu.com/s/1eQg3pvW, 提取密码为nhhd。此外,为方便使用,我还在IP表中记录了IP对应的城市的经纬度:
要声明的是,
本人不对数据的正确性作任何保证。
同时,提供几个用到的函数(代码待优化),供参考:
public class IpUtil {
private static final int MAX = 255;
/**
* 把IpRange拆成更小的IpRange,使得每个小的IpRange的前三个网段是相同的
* 例如把1.1.1.20-1.1.3.30拆成:
* 1.1.1.20-1.1.1.255
* 1.1.2.0-1.1.2.255
* 1.1.3.0-1.1.3.30
* @param range
* @return
*/
public static List<IpRange> split(IpRange range) {
List<IpRange> list = new ArrayList<IpRange>();
long p0, p1, p2;
long min = toLongWithFirstThreeParts(range.getStart());
long max = toLongWithFirstThreeParts(range.getEnd());
for (p0 = range.getStart().getP0(); p0 <= range.getEnd().getP0(); p0++) {
for (p1 = 0; p1 <= MAX; p1++) {
for (p2 = 0; p2 <= MAX; p2++) {
if (firstThreePartsToLong(p0, p1, p2)< min) {
continue;
}
if (firstThreePartsToLong(p0, p1, p2) > max) {
break;
}
IpBean newStart = new IpBean(p0, p1, p2, 0);
if (newStart.toLong() < range.getStart().toLong()) {
newStart = range.getStart();
}
IpBean newEnd = new IpBean(p0, p1, p2, 255);
if (newEnd.toLong() > range.getEnd().toLong()) {
newEnd = range.getEnd();
}
IpRange ipRange = new IpRange(newStart, newEnd);
list.add(ipRange);
}
}
}
return list;
}
/**
* 只计算前三段
* @return
*/
public static long toLongWithFirstThreeParts(IpBean bean) {
long p0 = bean.getP0();
long p1 = bean.getP1();
long p2 = bean.getP2();
return firstThreePartsToLong(p0, p1, p2);
}
public static long firstThreePartsToLong(long p0, long p1, long p2) {
return (p0 << 24) + (p1 << 16) + (p2 << 8);
}
/**
* 取得startIp-endIp这个IP段内所有的单个IP
* @param startIp
* @param endIp
* @return
*/
public static List<IpBean> findIpList(String startIp, String endIp) {
List<IpBean> list = new ArrayList<IpBean>();
IpBean startBean = toBean(startIp);
IpBean endBean = toBean(endIp);
long start = startBean.toLong();
long end = endBean.toLong();
long p0, p1, p2, p3;
for (p0 = startBean.getP0(); p0 <= endBean.getP0(); p0++ ) {
for (p1 = 0; p1 <= MAX; p1++) {
for (p2 = 0; p2 <= MAX; p2++) {
for (p3 = 0; p3 <= MAX; p3++) {
IpBean newIp = new IpBean();
newIp.setP0(p0);
newIp.setP1(p1);
newIp.setP2(p2);
newIp.setP3(p3);
long newLongVal = newIp.toLong();
if (start <= newLongVal && newLongVal <= end) {
list.add(newIp);
}
}
}
}
}
return list;
}
public static IpBean toBean(String ipStr) {
long[] ip = new long[4];
// 先找到IP地址字符串中.的位置
int position1 = ipStr.indexOf(".");
int position2 = ipStr.indexOf(".", position1 + 1);
int position3 = ipStr.indexOf(".", position2 + 1);
// 将每个.之间的字符串转换成整型
ip[0] = Long.parseLong(ipStr.substring(0, position1));
ip[1] = Long.parseLong(ipStr.substring(position1 + 1, position2));
ip[2] = Long.parseLong(ipStr.substring(position2 + 1, position3));
ip[3] = Long.parseLong(ipStr.substring(position3 + 1));
IpBean bean = new IpBean();
bean.setP0(ip[0]);
bean.setP1(ip[1]);
bean.setP2(ip[2]);
bean.setP3(ip[3]);
return bean;
}
}
/**
* 合并连续的、在同一城市的IP
*/
public void merge() {
IpExample example = new IpExample();
example.createCriteria().andStateEqualTo(IpConst.State.OK);
example.setOrderByClause("ipstartdigital asc");
List<Ip> list = mapper.selectByExample2(example);
logger.info("size={}", list.size());
Ip startIp = null;
Ip endIp = null;
int count = 0;
for (Ip ip : list) {
if (startIp == null) {
startIp = ip;
endIp = ip;
} else {
if (isMatched(endIp, ip) && isContinuous(endIp, ip) ) {
endIp = ip;
continue;
} else {
count++;
insert(startIp, endIp);
startIp = ip;
endIp = ip;
}
}
}
if (startIp != null && endIp != null) {
count++;
insert(startIp, endIp);
}
logger.info("count={}", count);
}
private boolean isContinuous(Ip endIp, Ip ip) {
return endIp.getIpenddigital().equals(ip.getIpstartdigital() - 1);
}
private void insert(Ip startIp, Ip endIp) {
Ip ip = new Ip();
Helper.copyFromNotNull(ip, startIp);
ip.setIpend(endIp.getIpend());
ip.setIpenddigital(endIp.getIpenddigital());
ip.setId(null);
logger.info("last ipstart={}, ipstartdigital={}, ipend={}, ipenddigital={}, province={}, city={}", ip.getIpstart(), ip.getIpstartdigital(), ip.getIpend(), ip.getIpenddigital(), ip.getProvince(), ip.getCity());
mapper.insert(ip);
}
private boolean isMatched(Ip x, Ip y) {
boolean result = false;
//国家+省+市是否相等
if (x != null && y != null) {
result = StringUtils.equals(x.getCountry(), y.getCountry())
&& StringUtils.equals(x.getProvince(), y.getProvince())
&& StringUtils.equals(x.getCity(), y.getCity());
}
return result;
}
- 大小: 80.9 KB
分享到:
相关推荐
淘宝IP地址库与API服务详解 一、淘宝IP地址库简介 淘宝IP地址库是阿里巴巴集团为满足广大开发者对IP地址解析的需求而推出的在线服务。它不仅提供了丰富的IP地址信息查询功能,还支持高精度的地理位置定位,以及运营...
首先,淘宝IP地址库是一个广泛使用的资源,它提供了一个庞大的IP地址到地理位置的映射,帮助开发者快速定位用户的位置。这个库通常以JSON格式存储,因为JSON是一种轻量级的数据交换格式,易于人阅读和编写,同时也...
淘宝IP地址库是一个提供免费的IP信息查询服务的数据库,用户可以利用这个库查询IP地址所在国家、区域、省份、城市以及运营商等详细信息。该数据库使用方便,不需要用户进行身份认证或注册即可使用。但是它有一个限制...
使用淘宝ip地址库的api查询ip地址信息。 TaobaoIPHelper.cs 代码如下:using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace LixinCommon{ /// /// 淘宝IP地址库...
“IP地址库2018024”是一个基于纯真数据库和淘宝地址库进行整合和更新的数据集合,具有高度的准确性和详尽性。它覆盖了超过480000个IP地址记录,精确到国家、省份以及城市级别,这对于需要进行地域定位的业务至关...
本文将详细讨论如何根据IP地址获取其所在的区域、运营商以及国家等信息,特别是在Java环境中利用淘宝IP地址库进行此类操作。 首先,IP地址是互联网上设备的唯一标识,它分为IPv4和IPv6两种格式。在IPv4中,IP地址由...
《IP地址库20181029(SQL Server)》是一个专为SQL Server设计的IP地址数据库,它提供了一种高效的方式来管理和查询全球范围内的IP地址信息。该数据库基于两个知名的数据源——纯真数据库和淘宝地址库,经过整合和...
并且会随着淘宝IP地址库实时更新。所以您获得的数据将会是最新的。 2.此3.0核心函数代码加密 其它2.0 1.0 版本完全开源 3.define('SINA_SAE', '0'); //是否启用新浪SAE平台1为使用0为不使用 4.define('REWRITE', ...
描述中提到,该IP地址库是基于“纯真数据库”和“淘宝地址库”重新制作的。"纯真数据库"是一个常见的中文IP地址数据库,由志愿者维护,包含了大量的IP地址与地理位置对应数据,而“淘宝地址库”可能来源于电商巨头...
并且会随着淘宝IP地址库实时更新。所以您获得的数据将会是最新的。 2.此3.0核心函数代码加密 其它2.0 1.0 版本完全开源 3.define('SINA_SAE', '0'); //是否启用新浪SAE平台1为使用0为不使用 4.define('REWRITE', ...
一个精确的IP地址库对于网络安全、网站管理、用户行为分析以及流量监测等领域来说,有着至关重要的作用。 “IP地址库20210512”正是这样一个为满足上述需求而精心制作的数据库资源。它的开发始于两个非常成熟的IP...
标题中的“IP地址库-...总的来说,这个“IP地址库-20180205(SQL)”是网络管理和数据分析的重要工具,它整合了纯真IP地址库和淘宝地址库的数据,提供了丰富的IP信息,适用于多种场景,从网络安全到用户体验优化。
IP地址值库(基于纯真数据库和淘宝地址库进行的重制)。精确到市级(国家,省,市),包含ISP信息(原纯真记录数 > 480000,合并去重后近30w) 新版的地址20200325 ...
总的来说,使用Python2.7结合淘宝IP接口获取地理位置信息是一个实用的技巧,特别适用于需要快速定位IP地址的应用场景。同时,了解如何处理网络请求和解析JSON数据也是Python开发者必备的基本技能。在实际项目中,你...
《IP地址库20181219(SQL Server)》是一个专为SQL Server设计的IP地址数据库,它结合了“纯真数据库”和“淘宝地址库”的数据,提供了全面且精确的IP地理位置信息。这个数据库经过重置和优化,能够提供超过30万个...
在这个"淘宝IP地址解析"的例子中,我们将深入探讨如何使用REST客户端来解析特定IP地址的信息,以及可能涉及的技术和概念。 首先,我们需要理解REST的基本原则。REST架构风格强调了资源的概念,每个资源都有一个唯一...