您的位置:首页 > 其它

根据IP判断地理位置

2017-04-24 18:31 316 查看

根据IP判断地理位置

首先,当然是要有IP数据库,指明某一段IP代表哪个地方,本文采用的是txt格式的数据文件

IP数据库中的IP全部转换成了Long型,并且经过排序,这是为了方便二分查找

初始化操作: 载入IP数据文件

将数据文件按行读入内存,IP数据文件的格式如下:

起始IP结束IP国家未知运营商
1000000020000000中国北京市北京市海淀区未知电信
读取文件:

ipFile = new File(Class.forName("IPMapping").getClassLoader().getResource("ip_standard.txt").getFile());

List<String> lines = null;
lines = Files.readLines(ipFile, Charsets.UTF_8);


遍历每一行信息后存放在
ImmutableList
中:

static ImmutableList<Long> START_IP_INDEX;
static ImmutableList<Long> END_IP_INDEX;
static ImmutableList<String> IP_INFO;

START_IP_INDEX = new ImmutableList.Builder<Long>().addAll(startIpIndexTmp.iterator()).build();
END_IP_INDEX = new ImmutableList.Builder<Long>().addAll(endIpIndexTmp.iterator()).build();
IP_INFO = new ImmutableList.Builder<String>().addAll(ipInfoTmp.iterator()).build();


判断IP的准确性

需要查找的IP为标准的
XXX.XXX.XXX.XXX
格式

在进行查找之前需要判断该IP字符串是否有效:

public static boolean isValid(String ipStr) {
if (StringUtils.isBlank(ipStr))
return false;

final String IP_FORMAT = "((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)";

return (ipStr.matches(IP_FORMAT)) ? true : false;
}


有效的IP字符串可以转化成Long型

public static long ip2long(String ipStr) {
Long ipInLong = 0L;
if (isValid(ipStr)) {
String[] partIp = StringUtils.split(ipStr.trim(), "\\.");
for (int i = 0; i < 4; i++)
ipInLong = ipInLong << 8 | Integer.parseInt(partIp[i]);
}
return ipInLong;
}


通过二分查找判断该IP是否有对应的信息

和普通的二分相比,键的值是一对数,而且这对数的左值小于等于右值

改下了二分查找如下:

public int binarySearch(long ip) {

int low = 0;
int high = START_IP_INDEX.size() - 1;
while (low <= high) {
int middle = (low + high) / 2;
if (ip >= START_IP_INDEX.get(middle) && (ip <= END_IP_INDEX.get(middle)))
return middle;
if (ip < START_IP_INDEX.get(middle))
high = middle - 1;
else
low = middle + 1;
}
return -1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二分查找