Java的IPv4/IPv6网络计算和验证?

Jos*_*eph 9 java networking ip-address

我正在寻找一个类似于Net_IPv4Net_IPv6但是为Java编写的包.它需要能够执行以下操作:

  • 验证地址是否有效(例如127.0.0.1有效,127.0.0.257不有效)
  • 如果子网中包含地址则返回(例如127.0.0.11在127.0.0.0/28中)
  • 返回给定子网的广播地址(例如,对于127.0.0.0/28,它是127.0.0.15)

如果它还可以:它会很棒:

  • 按顺序返回子网的地址列表
  • 对地址列表进行排序

我可能会写一个包来做这一切,但如果有人已经经历了麻烦并且很可能做得更好,我就是在使用它.有人知道这样的一个或多个包可以做到这一切吗?我们正在扩展到IPv6,因此如果可能,它需要同时适用于IPv4和IPv6.

我感谢任何帮助.

JLR*_*JLR 5

它仅适用于IPv4,但属于Commons NetSubnetUtils类具有您正在寻找的功能.基于此,您可以编写IPv6版本并将其贡献给项目!:)


Edi*_*vic 5

也许CIDRUtils可以帮到你.它使您能够将CIDR表示法转换为IP范围.

免责声明:我是CIDRUtils的作者.


Sea*_*n F 5

IPAddress Java 库以包括子网在内的多态方式支持 IPv4 和 IPv6。链接中提供了 javadoc。免责声明:我是项目经理。

您列出的所有用例都支持 IPv4 和 IPv6 透明。换句话说,它与大多数其他实用程序的不同之处在于以下代码与 IPv4 或 IPv6 作为输入字符串的工作方式相同。

验证地址是否有效

    String str = "::1";
    IPAddressString addrString = new IPAddressString(str);
    try {
         IPAddress addr = addrString.toAddress();
         ...
    } catch(IPAddressStringException e) {
        //e.getMessage provides validation issue
    }
Run Code Online (Sandbox Code Playgroud)

如果地址包含在子网中,则返回

    String str = "1::1";
    String subnetStr = "1::/64";
    IPAddressString addrString = new IPAddressString(str);
    IPAddressString subnetString = new IPAddressString(subnetStr);
    try {
         IPAddress addr = addrString.toAddress();
         IPAddress subnet = subnetString.toAddress();
         boolean isContained = subnet.contains(addr); //true in this case
         ...
    } catch(IPAddressStringException e) {
        //e.getMessage provides validation issue
    }
Run Code Online (Sandbox Code Playgroud)

返回给定子网的广播地址

    String subnet = "127.0.0.0/28";
    IPAddressString subnetString = new IPAddressString(subnet);
    try {
         IPAddress subnet = subnetString.toAddress();
         IPAddress broadcastAddr = subnet.getHighest();
         ...
    } catch(IPAddressStringException e) {
        //e.getMessage provides validation issue
    }
Run Code Online (Sandbox Code Playgroud)

按顺序返回子网的地址列表

    String subnet = "127.0.0.0/28";
    IPAddressString subnetString = new IPAddressString(subnet);
    try {
         IPAddress subnet = subnetString.toAddress();
         for(IPAddress addr : subnet) {
             ...
         }
    } catch(IPAddressStringException e) {
        //e.getMessage provides validation issue
    }
Run Code Online (Sandbox Code Playgroud)

对地址列表进行排序

    List<IPAddressString> addrs; 
    Collections.sort(addrs); //IPAddressString implements Comparable
Run Code Online (Sandbox Code Playgroud)

获取一组子网和地址列表(对 AhmedRana 的响应):

    IPAddress subnet = new IPAddressString("192.168.0.0/28").getAddress();
    IPAddress newSubnets = subnet.adjustPrefixLength(1, false);
    System.out.println(newSubnets); //192.168.0.0-8/29
    HashSet<IPAddress> subnetSet = new HashSet<IPAddress>();
    ArrayList<IPAddress> addrList = new ArrayList<IPAddress>();
    for(IPAddress addr : newSubnets.getIterable()) {
        subnetSet.add(addr.toPrefixBlock());
        addrList.add(addr);
    }
    System.out.println(subnetSet);//[192.168.0.0/29, 192.168.0.8/29]

    System.out.println(addrList);
                //[192.168.0.0/29, 192.168.0.1/29, 192.168.0.2/29,
                //192.168.0.3/29, 192.168.0.4/29, 192.168.0.5/29,
                //192.168.0.6/29, 192.168.0.7/29, 192.168.0.8/29,
                //192.168.0.9/29, 192.168.0.10/29, 192.168.0.11/29,
                //192.168.0.12/29, 192.168.0.13/29, 192.168.0.14/29,
                //192.168.0.15/29]
Run Code Online (Sandbox Code Playgroud)

可以有很多地址。获取新子网列表的更有效方法是使用前缀块迭代器,它遍历前缀块子网,如下所示:

    IPAddress subnet = new IPAddressString("192.168.0.0/28").getAddress();
    IPAddress newSubnets = subnet.adjustPrefixLength(1, false);
    System.out.println(newSubnets); // 192.168.0.0-8/29
    Iterator<? extends IPAddress> iterator = newSubnets.prefixBlockIterator();
    while (iterator.hasNext()) {
        System.out.println(iterator.next());
    }
    // 192.168.0.0/29
    // 192.168.0.8/29
Run Code Online (Sandbox Code Playgroud)