业务场景:解析IP段

91 阅读2分钟

整型 IP(Integer IP)是一种将 IP 地址表示为整数的方式,用于方便存储和计算。在计算机内部,IP 地址通常以整数形式存储,而不是点分十进制形式。

IPv4 地址由 32 位组成,可以表示为一个 32 位的二进制数。将这个二进制数转换为十进制整数即可得到整型 IP。

以下是一个示例代码,展示了如何将 IPv4 地址转换为整型 IP:

public long pointToPointConversionToInteger(String ip) {
    String[] split = ip.split("\\.");
    return (Long.parseLong(split[0]) << 24) | (Long.parseLong(split[1]) << 16) | (Long.parseLong(split[2]) << 8) | Long.parseLong(split[3]);
}

public String integerConversionToPointToPoint(long ip) {
    return ((ip & 0xff000000L) >> 24) + "." + ((ip & 0x00ff0000L) >> 16) + "." + ((ip & 0x0000ff00L) >> 8) + "." + (ip & 0x000000ffL);
}

在上面的示例代码中,我们定义了 pointToPointConversionToInteger() 方法和 integerConversionToPointToPoint() 方法来实现 IP 地址与整型 IP 之间的转换。

pointToPointConversionToInteger() 方法接受一个 IPv4 地址字符串作为参数,并将其拆分为四个部分。然后,我们将每个部分转换为整数,并通过移位和按位逻辑或操作将它们合并到一个长整型变量中。最终返回这个整型 IP。

integerConversionToPointToPoint() 方法接受一个整型 IP 作为参数,通过右移和按位与操作将其拆分成四个部分,并将其转换为点分十进制的 IP 地址形式。最后返回 IP 地址字符串。

将点分制IP转换为长整型以方便进行区间合并。以下是一段示例代码:

public void mergerOfIntervals(List<long[]> intervals, TreeMap<Long, Long> map) {
    for (long[] interval : intervals) {
        long l2 = interval[0];
        long r2 = interval[1];
        for (Map.Entry<Long, Long> entry = map.floorEntry(r2); entry != null && entry.getValue() >= l2; entry = map.floorEntry(r2)) {
            long l1 = entry.getKey();
            long r1 = entry.getValue();
            l2 = Math.min(l2, l1);
            r2 = Math.max(r2, r1);
            map.remove(l1);
        }
        map.put(l2, r2);
    }
}

intervals数组为存放IP段的列表。map存放区间,key为左端点,value为右端点。传入IP格式以,分割IP与IP段,有-的为IP段,否则为单个IP

@Test
public void asdf() {
    LinkedList<String> list = resolveTheIPString("0.0.0.0-0.1.0.0,127.255.255.255");
    for (String s : list) {
        System.out.println(s);
    }
}

public LinkedList<String> resolveTheIPString(String ip) {
    LinkedList<long[]> intervals = new LinkedList<>();
    String[] splitCommas = ip.split(",");
    for (String splitComma : splitCommas) {
        String[] splitBars = splitComma.split("-");
        if (splitBars.length == 2) {
            intervals.add(new long[]{pointToPointConversionToInteger(splitBars[0]), pointToPointConversionToInteger(splitBars[1])});
        } else {
            intervals.add(new long[]{pointToPointConversionToInteger(splitBars[0]), pointToPointConversionToInteger(splitBars[0])});
        }
    }
    TreeMap<Long, Long> map = new TreeMap<>();
    mergerOfIntervals(intervals, map);
    LinkedList<String> list = new LinkedList<>();
    for (Map.Entry<Long, Long> entry : map.entrySet()) {
        long from = entry.getKey();
        long to = entry.getValue();
        for (long i = from; i <= to; i++) {
            list.add(integerConversionToPointToPoint(i));
        }
    }
    return list;
}

从返回的list中即可获取区间内所有的IP。