如何从 IP 范围中获取单独的连续 IP 块?

How can i get individual sequential IP blocks from an IP Range?

给定一个 ip 范围,例如 41.216.124.0-41.216.127.27,我想得到以下内容:

41.216.124.*

41.216.125.*

41.216.126.*

41.216.127.*

同样给定 128.1.0.1-191.255.255.254 我想单独列出它们 128.1.0.1-255

128.1.1-255.*

128.2-255.*.*

129-190.*.*

191.0-254.*.*

191.255.*

191.255.255.*

我尝试了各种方法,包括使用正则表达式来匹配不重复的字段并尝试找出差异。我遇到了一个非常好的库 https://seancfoley.github.io/IPAddress/ by https://whosebug.com/users/6801443/sean-f 我尝试了以下方法,但似乎无法在文档中找到实现它的方法。

 var ipRange1 = "128.1.0.1-191.255.255.254"; //ipRange1 example
 var ipRange2 = "41.216.124.0-41.216.127.27"; //ipRange2 example
 import inet.ipaddr.IPAddress;
 import inet.ipaddr.IPAddressSeqRange;
 import inet.ipaddr.IPAddressString; 
 String[] subString = ipRange2.split("-");  
 IPAddressString startIP = new IPAddressString(subString[0]);
 IPAddressString endIP = new IPAddressString(subString[1]);
 IPAddress one = startIP.getAddress(), two = endIP.getAddress();
 IPAddressSeqRange range = one.toSequentialRange(two);
 var ips = new HashSet<String>();
 IPAddress blocks[] = range.spanWithSequentialBlocks(); // 41.216.124-126.```*```

即使没有这个库,在 Java 中是否仍然可以做到这一点?我试图查询的 API 使用 IP 前缀,这就是为什么我要解决所有问题。

这是我的初步尝试。您必须意识到您所说的范围非常大。我正在使用长整数来避免 LongStream 范围内的有符号整数问题。

    public static void main(String[] args) {
        printIPs("192.148.233.0", "192.148.245.3", 32);

    }

    public static void printIPs(String start, String end, int mask) {
        LongStream.rangeClosed(toLong(start, mask), toLong(end, mask))
                .mapToObj(ip-> toIP(ip, mask))
                .forEach(System.out::println);

    }

    public static String toIP(long lv, int mask) {
        lv <<= (32-mask);
        String ip = String.join(".",
                Long.toString((lv >> 24) & 0xFF),
                Long.toString((lv >> 16) & 0xFF),
                Long.toString((lv >> 8) & 0xFF),
                Long.toString(lv & 0xFF));
        return ip;
    }

    public static long toLong(String ip, int mask) {
        String[] n = ip.split("\.");

        long v = Integer.valueOf(n[0]);
        v <<= 8;
        v |= Integer.valueOf(n[1]);
        v <<= 8;
        v |= Integer.valueOf(n[2]);
        v <<= 8;
        v |= Integer.valueOf(n[3]);

        return v >> (32-mask);
    }
}
}