代码之家  ›  专栏  ›  技术社区  ›  loraderon

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

  •  9
  • loraderon  · 技术社区  · 16 年前

    我在找一个类似于 Net_IPv4 Net_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 回复  |  直到 6 年前
        1
  •  6
  •   JLR    15 年前

    它只适用于IPv4,但是 SubnetUtils 属于的类 Commons Net 具有您要查找的功能。在此基础上,您可以编写一个IPv6版本并将其贡献给项目!:)

        2
  •  5
  •   Edin Dazdarevic    11 年前

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

    免责声明:我是《Cidrutils》的作者。

        3
  •  3
  •   jgonian    9 年前

    我是 commons-ip-math 一个开源的Java库,它提供了一个丰富的API来处理最常用的IPv4、IPv6和AS数的计算。虽然它只是最近才被开放的来源,但它已经在内部进行了多年的战斗测试。 RIPE NCC . 请看下面如何使用它。

    (所有的例子都使用类似的ipv6和as-number语法。只需使用ipv6、ipv6range、asn和asrange类即可)。

    • 验证地址是否有效(例如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类型实现了类似的接口:

    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]
    
        4
  •  2
  •   Sean F    6 年前

    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
    
        5
  •  0
  •   Jon Cram    15 年前

    inetaddress类和相关的子类将是一个非常好的开始位置: http://java.sun.com/j2se/1.4.2/docs/api/java/net/InetAddress.html