您的位置:首页 > 理论基础 > 计算机网络

Java工具类之通过IP获取对应的位置信息及网络供应商

2016-08-06 16:39 477 查看
  由于近期人员管理协调的事情较多,有近小两个月没有分享点滴技术,今将忙里偷闲做的通过IP获取对应的位置信息及网络供应商的工具类及其使用到的数据源分享一下,以飨读者。

    该问题主要分为以下x步来解决:

    1、获取ip与位置及供应商以及网络供应商映射表

          我已将整理好的20160630的纯真网络的映射表共享于天亮教育百度云共享中,地址为http://pan.baidu.com/s/1pJJrcqJ#path=%252F%25E5%25A4%25A9%25E4%25BA%25AE%25E6%2595%2599%25E8%2582%25B2%252F%25E4%25BC%2598%25E8%25B4%25A8%25E6%2596%2587%25E6%25A1%25A3

     2、将映射表构建成按IP地址有序的数组

            2.1 将IP转换为长整型来进行比较

                   我们知道每个IP或是时间类型,其均应一个长整理数值,来唯一值化和标志它。

                   其工具类为:

package com.letv.datamining.warehouse.utils;
/**
* 将IP与长整型数值互换
* @author zhouerliang
*
*/
public class IPToLongConvertUtil {

// 将127.0.0.1形式的IP地址转换成十进制整数,这里没有进行任何错误处理
public static long ipToLong(String strIp) {
long[] ip = new long[4];
// 先找到IP地址字符串中.的位置
int position1 = strIp.indexOf(".");
int position2 = strIp.indexOf(".", position1 + 1);
int position3 = strIp.indexOf(".", position2 + 1);
// 将每个.之间的字符串转换成整型
ip[0] = Long.parseLong(strIp.substring(0, position1));
ip[1] = Long.parseLong(strIp.substring(position1 + 1, position2));
ip[2] = Long.parseLong(strIp.substring(position2 + 1, position3));
ip[3] = Long.parseLong(strIp.substring(position3 + 1));
return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
}

// 将十进制整数形式转换成127.0.0.1形式的ip地址
public static String longToIP(long longIp) {
StringBuffer sb = new StringBuffer("");
// 直接右移24位
sb.append(String.valueOf((longIp >>> 24)));
sb.append(".");
// 将高8位置0,然后右移16位
sb.append(String.valueOf((longIp & 0x00FFFFFF) >>> 16));
sb.append(".");
// 将高16位置0,然后右移8位
sb.append(String.valueOf((longIp & 0x0000FFFF) >>> 8));
sb.append(".");
// 将高24位置0
sb.append(String.valueOf((longIp & 0x000000FF)));
return sb.toString();
}

public static void main(String[] args) {
String ipStr = "127.0.0.1";
long longIp = IPToLongConvertUtil.ipToLong(ipStr);
System.out.println("整数形式为:" + longIp);
System.out.println("整数" + longIp + "转化成字符串IP地址:"
+ IPToLongConvertUtil.longToIP(longIp));
// ip地址转化成二进制形式输出
System.out.println("二进制形式为:" + Long.toBinaryString(longIp));
}

}
                2.2 构建按IP地址对应的长整型有序的数组
 package com.letv.datamining.warehouse.utils;

import java.io.BufferedReader;
import java.util.LinkedList;

/**
* 构建按ip对应的长整型值升序的有序数组,并输入ip返回对应的网络供应商
*
* @author zhouerliang
*
*/
public class IPAndProviderSearchUtil {
public static class IPAndProviderPojo implements
Comparable<IPAndProviderPojo> {
private String start_ip;
private String end_ip;
private long start_ip_long;
private long end_ip_long;
private String provideName;

public IPAndProviderPojo(String start_ip, String end_ip,
String provideName) {
super();
this.start_ip = start_ip;
this.end_ip = end_ip;
this.provideName = provideName;

this.start_ip_long = IPToLongConvertUtil.ipToLong(this.start_ip);
this.end_ip_long = IPToLongConvertUtil.ipToLong(this.end_ip);

}

@Override
public int compareTo(IPAndProviderPojo o) {
if (this.start_ip_long > o.start_ip_long) {
return -1;
}
if (this.start_ip_long < o.start_ip_long) {
return 1;
}
return 0;
}

public String getStart_ip() {
return start_ip;
}

public void setStart_ip(String start_ip) {
this.start_ip = start_ip;
}

public String getEnd_ip() {
return end_ip;
}

public void setEnd_ip(String end_ip) {
this.end_ip = end_ip;
}

public long getStart_ip_long() {
return start_ip_long;
}

public void setStart_ip_long(long start_ip_long) {
this.start_ip_long = start_ip_long;
}

public long getEnd_ip_long() {
return end_ip_long;
}

public void setEnd_ip_long(long end_ip_long) {
this.end_ip_long = end_ip_long;
}

public String getProvideName() {
return provideName;
}

public void setProvideName(String provideName) {
this.provideName = provideName;
}

@Override
public String toString() {
return "IPAndProviderPojo [start_ip=" + start_ip + ", end_ip="
+ end_ip + ", start_ip_long=" + start_ip_long
+ ", end_ip_long=" + end_ip_long + ", provideName="
+ provideName + "]";
}
}

/**
* 二分查找特定整数在整型数组中的位置(递归)
*
* @paramdataset
* @paramdata
* @parambeginIndex
* @paramendIndex
* @returnindex
*/
public static int binarySearch(IPAndProviderPojo[] dataset, long aidValue,
int beginIndex, int endIndex) {
int midIndex = (beginIndex + endIndex) / 2;
if (aidValue < dataset[beginIndex].start_ip_long
|| aidValue > dataset[endIndex].end_ip_long
|| beginIndex > endIndex) {
return -1;
}
if (aidValue < dataset[midIndex].start_ip_long) {
return binarySearch(dataset, aidValue, beginIndex, midIndex - 1);
} else if (aidValue > dataset[midIndex].end_ip_long) {
return binarySearch(dataset, aidValue, midIndex + 1, endIndex);
} else {
return midIndex;
}
}

public IPAndProviderPojo[] ipAndProviderPojoArray = null;

public IPAndProviderSearchUtil(String configFile, String charset) {
BufferedReader br = IOUtil.getTextBufferedReader4ConfigFile(configFile, charset);
LinkedList<IPAndProviderPojo> pojoList = new LinkedList<IPAndProviderPojo>();

try {
String temp_line = null;
String[] col_array = null;
while ((temp_line = br.readLine()) != null) {
if (StringOperatorUtil.isNotBlank(temp_line)) {
col_array = temp_line.split(StaticValue.separator_tab);
if (col_array.length == 3) {
pojoList.add(new IPAndProviderPojo(col_array[0],
col_array[1], col_array[2]));
} else {
System.out.println("error line=" + temp_line);
throw new Exception("发现ip and providerName格式错误条目!");
}
}
}
br.close();
// System.out.println("pojoList.size()=" + pojoList.size());
ipAndProviderPojoArray = new IPAndProviderPojo[pojoList.size()];
// 将list转化为array存储
pojoList.toArray(ipAndProviderPojoArray);
} catch (Exception e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
String configFile = "ip_location_config/ip_location_relation.txt";
String aidValue = "123.125.26.228";
IPAndProviderSearchUtil searchUtil = new IPAndProviderSearchUtil(
configFile, "utf-8");

int findIndex = searchUtil.binarySearch(
searchUtil.ipAndProviderPojoArray,
IPToLongConvertUtil.ipToLong(aidValue), 0,
searchUtil.ipAndProviderPojoArray.length - 1);
if (findIndex < 0) {
System.out.println("未找到");
} else {
IPAndProviderPojo pojo = searchUtil.ipAndProviderPojoArray[findIndex];
System.out.println(pojo.toString());
}

// System.out.println(searchUtil.ipAndProviderPojoArray.length);

}
}


                  3、 功能与准确性测试
                         功能测试的api均已在上边贴出的源代码中,

                         其准确性我拿身边及随意百度的IP及地址值和网络供应商,皆准确,且粒度更细。达到相当的可用性。

               

更多学习讨论,      请加入官方QQ技术群320349384,

                                天亮教育官方群318971238,

                                 官方天亮论坛:http://bbs.yuqing36524.com/

                                 天亮教育视频链接:http://pan.baidu.com/s/1pJJrcqJ
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息