【问题标题】:How can i get individual sequential IP blocks from an IP Range?如何从 IP 范围中获取单独的连续 IP 块?
【发布时间】:2020-05-05 05:06:45
【问题描述】:

给定一个 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://stackoverflow.com/users/6801443/sean-f 遇到了一个非常好的库https://seancfoley.github.io/IPAddress/ 我尝试了以下方法,但似乎无法在文档中找到一种方法。

 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 前缀,这就是我要费尽心思的原因。

【问题讨论】:

    标签: java ip-address


    【解决方案1】:

    这是我最初的尝试。你必须意识到你所说的范围非常大。我使用 long 来避免 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);
        }
    }
    }
    

    【讨论】:

    • 不是我想要的确切解决方案,但这教会了很多,这是一个很好的起点。
    • 我修改了程序以提供额外的功能。我添加了一个 CIDR“掩码”来指定您想要的输出方式。通过传入 32 作为第三个参数,它的行为就像往常一样。例如,如果您提供 16,它将打印两个值之间的所有 /16,忽略无关紧要的位。
    猜你喜欢
    • 2021-12-15
    • 2012-05-07
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    • 2022-01-14
    • 1970-01-01
    相关资源
    最近更新 更多