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

时间:2009-02-17 18:08:02

标签: 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。

我感谢任何帮助。

5 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:5)

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

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

答案 2 :(得分:3)

我是commons-ip-math的主要贡献者,RIPE NCC是一个开源Java库,提供丰富的API来处理最常见的IPv4,IPv6和AS号计算。虽然它最近才开源,但它已在{{3}}内进行了多年的战斗测试。了解如何在下面使用它。

(所有示例都使用类似的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]

答案 3 :(得分:2)

The IPAddress Java library以多态方式支持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

答案 4 :(得分:0)

InetAddress类和相关的子类将是一个非常好的起点: http://java.sun.com/j2se/1.4.2/docs/api/java/net/InetAddress.html