10

我正在寻找一个类似于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。

我很感激任何帮助。

4

5 回答 5

6

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

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

于 2013-02-23T14:20:39.827 回答
5

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

于 2009-02-18T18:30:40.370 回答
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
    }

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

    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
    }

返回给定子网的广播地址

    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
    }

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

    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
    }

对地址列表进行排序

    List<IPAddressString> addrs; 
    Collections.sort(addrs); //IPAddressString implements Comparable

获取一组子网和地址列表(响应 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]

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

    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
于 2016-10-17T06:29:29.593 回答
4

我是commons-ip-math的主要贡献者,这是一个开源 Java 库,它提供了丰富的 API 来处理最常见的 IPv4、IPv6 和 AS 编号计算。尽管它只是最近才开源,但它已经在RIPE NCC内部进行了多年的实战测试。看看如何在下面使用它。

(所有示例都使用类似的 IPv6 和 AS 编号语法。只需使用 Ipv6、Ipv6Range、Asn 和 AsnRange 类代替)。

  • 验证地址是否有效(例如 127.0.0.1 有效,127.0.0.257 无效)
Ipv4.parse("127.0.0.1");     // IPv4 representation of "127.0.0.1"
Ipv4.parse("127.0.0.257");   // IllegalArgumentException
  • 如果地址包含在子网中,则返回(例如 127.0.0.11 在 127.0.0.0/28 中)
Ipv4Range.parse("127.0.0.0/28").contains(Ipv4.parse("127.0.0.11"));  //true  
  • 返回给定子网的广播地址(例如,对于 127.0.0.0/28,它是 127.0.0.15)
Ipv4Range.parse("127.0.0.0/28").start().upperBoundForPrefix(28)  // 127.0.0.15
  • 按顺序返回子网的地址列表
// Range types are Iterable
for (Ipv4 ipv4 : Ipv4Range.parse("127.0.0.0/30")) {
  System.out.println(ipv4);
}
// Will print:
127.0.0.0
127.0.0.1
127.0.0.2
127.0.0.3
  • 对地址列表进行排序

尽管该库提供了范围类型的比较器(例如比较子网的大小),但没有针对单个地址的比较器。然而,编写自己的代码相当简单,因为 IPv4、IPv6 和 ASN 类型实现了 Comparable 接口:

List<Ipv4> list = new ArrayList<Ipv4>();
list.add(Ipv4.of("0.0.0.3"));
list.add(Ipv4.of("0.0.0.4"));
list.add(Ipv4.of("0.0.0.2"));
list.add(Ipv4.of("0.0.0.1"));
Collections.sort(list, new Comparator<Ipv4>() {
    @Override
    public int compare(Ipv4 left, Ipv4 right) {
        return left.compareTo(right);
    }
});
System.out.println(list);
// Will print:
[0.0.0.1, 0.0.0.2, 0.0.0.3, 0.0.0.4]
于 2015-04-06T21:14:24.777 回答
0

InetAddress类和相关的子类将是一个很好的起点。

于 2009-02-18T07:42:21.770 回答