以IPV4举例,IPv4使用32位(4字节)地址,假设库中存的是点分十进制数据
方法
(1):将点分十进制数转化为long,排序后进行二分查找,如果只查一次的话,复杂度较大,查的次数多比较划算
(2):使用布隆过滤器,适合查不存在的数据,查存在的数据不一定准确,有误差,但是效率高
(3):将数据转化为二进制,建立一颗01二叉树,然后查找
public class IPUtil {
// 用于高位对应
public long ip2Long(String ipString) {
String[] ipSlices = ipString.split("\\.");
long rs = 0;
for (int i = 0; i < ipSlices.length; i++) {
long longSlice = Long.parseLong(ipSlices[i]) << (8 * i);
rs = rs | longSlice;
}
return rs;
}
// 用于压缩数据
public int ip2Int(String ipString) {
// 取 ip 的各段
String[] ipSlices = ipString.split("\\.");
int rs = 0;
for (int i = 0; i < ipSlices.length; i++) {
// 将 ip 的每一段解析为 int,并根据位置左移 8 位
int intSlice = Integer.parseInt(ipSlices[i]) << (8 * i);
// 或运算
rs = rs | intSlice;
}
return rs;
}
public String int2Ip(int ipInt) {
String[] ipString = new String[4];
for (int i = 0; i < 4; i++) {
// 每 8 位为一段,这里取当前要处理的最高位的位置
int pos = i * 8;
// 取当前处理的 ip 段的值
int and = ipInt & (255 << pos);
// 将当前 ip 段转换为 0 ~ 255 的数字,注意这里必须使用无符号右移
ipString[i] = String.valueOf(and >>> pos);
}
return String.join(".", ipString);
}
}