IPv6验证

问题描述 投票:9回答:6

我使用IPAddressUtil.isIPv6LiteralAddress (ipAddress)方法验证IPv6,但此方法因IPV6的ipv6-address / prefix-length格式(格式在RFC 4291第2.3节中提到)而失败。

有谁知道任何验证“ipv6-address / prefix-length”格式的验证器?

IPV6的法律陈述

  1. ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
  2. 2001:DB8:0:0:8:800:200℃:417A
  3. FF01:0:0:0:0:0:0:101
  4. 0:0:0:0:0:0:0:1
  5. 0:0:0:0:0:0:0:0
  6. 2001:DB8 :: 8:800:200C:417A
  7. FF01 :: 101
  8. ::1
  9. ::
  10. 0:0:0:0:0:0:13.1.68.3
  11. 0:0:0:0:0:FFFF:129.144.52.38
  12. ::13.1.68.3
  13. FFFF:129.144.52.38
  14. 2001:0DB8:0000:CD30:0000:0000:0000:0000/60
  15. 2001:0DB8 :: CD30:0:0:0:0/60
  16. 2001:0DB8:0:CD30 :: / 60

不是IPV6的合法陈述

  1. 2001:0DB8:0:CD3 / 60
  2. 2001:0DB8 :: CD30 / 60
  3. 2001:0DB8 :: CD3 / 60
java regex parsing validation ipv6
6个回答
2
投票

看看这是否有效:

try {
    if (subjectString.matches(
        "(?ix)\\A(?:                                                  # Anchor address\n" +
        " (?:  # Mixed\n" +
        "  (?:[A-F0-9]{1,4}:){6}                                # Non-compressed\n" +
        " |(?=(?:[A-F0-9]{0,4}:){2,6}                           # Compressed with 2 to 6 colons\n" +
        "     (?:[0-9]{1,3}\\.){3}[0-9]{1,3}                     #    and 4 bytes\n" +
        "     \\z)                                               #    and anchored\n" +
        "  (([0-9A-F]{1,4}:){1,5}|:)((:[0-9A-F]{1,4}){1,5}:|:)  #    and at most 1 double colon\n" +
        " |::(?:[A-F0-9]{1,4}:){5}                              # Compressed with 7 colons and 5 numbers\n" +
        " )\n" +
        " (?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.){3}  # 255.255.255.\n" +
        " (?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])           # 255\n" +
        "|     # Standard\n" +
        " (?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}                    # Standard\n" +
        "|     # Compressed\n" +
        " (?=(?:[A-F0-9]{0,4}:){0,7}[A-F0-9]{0,4}               # Compressed with at most 7 colons\n" +
        "    \\z)                                                #    and anchored\n" +
        " (([0-9A-F]{1,4}:){1,7}|:)((:[0-9A-F]{1,4}){1,7}|:)    #    and at most 1 double colon\n" +
        "|(?:[A-F0-9]{1,4}:){7}:|:(:[A-F0-9]{1,4}){7}           # Compressed with 8 colons\n" +
        ")/[A-F0-9]{0,4}\\z                                                    # Anchor address")) 
        {
        // String matched entirely
    } else {
        // Match attempt failed
    } 
} catch (PatternSyntaxException ex) {
    // Syntax error in the regular expression
}

近一年前我购买了一个名为RegexMagic的非常有用的程序,用于我计划使用的一些复杂的正则表达式。

这被认为是Java,所以它应该编译,我假设/ 60可以在0000和FFFF的范围之间,你可以修改最后一部分。

/ [A-F0-9] {0,4}是我添加到正则表达式以匹配您的示例。


4
投票

您可以使用Guava库,特别是使用com.google.common.net.InetAddresses类,调用isInetAddress()


0
投票

严格地说,2.3节没有描述地址表示,而是表示地址前缀(甚至“全长”前缀与地址不同)。

IPv6地址前缀由符号表示:ipv6-address / prefix-length其中ipv6-address是第2.2节中列出的任何符号中的IPv6地址。

这意味着如果您需要验证地址,您可以安全地忽略此格式。


0
投票

我的想法是将它分为两​​部分,前缀地址和前缀len。

1.验证前缀地址使用一些正则表达式来验证IPv6地址 2.验证前缀len必须是整数 3.前缀地址只能有':'小于prefix len divided by 16的结果 4.其他逻辑也必须考虑,离开TODO,对不起:(

  private int validateIPv6AddrWithPrefix(String address) {
        int occurCount = 0;
        for(char c : address) {
            if(c=='/'){
                occurCount++;
            }
        }
        if(occurCount != 1){
         //not good, to much / character
            return -1;
        }
        /* 2nd element should be an integer */
        String[] ss = pool.getAddress().split("/");
        Integer prefixLen = null;
        try{
            prefixLen = Integer.valueOf(ss[1]);
                    // TODO validate the prefix range(1, 128)

        }catch(NumberFormatException e) {
            /* not a Integer */
            return -1;
        }
        /* 1st element should be ipv6 address */
        if(!IPaddrUtilities.isIPv6Address(ss[0])) {
            return -1;
        }
        /* validate ':' character logic */
        occurCount = 0;
        for(char c : ss[0].toCharArray()){
            if(c==':') {
                occurCount++;
            }
        }
        if(occurCount >= prefixLen/16) {
            // to much ':' character
            return -1;
        }
        return 0;
    }

0
投票

我在java中尝试了以下正则表达式,它适用于IPV4和IPV6

public class Utilities {
private static Pattern VALID_IPV4_PATTERN = null;
private static Pattern VALID_IPV6_PATTERN = null;
private static final String ipv4Pattern = "(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])";
private static final String ipv6Pattern = "([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}";

static {
try {
  VALID_IPV4_PATTERN = Pattern.compile(ipv4Pattern, Pattern.CASE_INSENSITIVE);
  VALID_IPV6_PATTERN = Pattern.compile(ipv6Pattern, Pattern.CASE_INSENSITIVE);
   } catch (PatternSyntaxException e) {
  //logger.severe("Unable to compile pattern", e);
 }
}

 /**
 * Determine if the given string is a valid IPv4 or IPv6 address.  This method
 * uses pattern matching to see if the given string could be a valid IP address.
 *
 * @param ipAddress A string that is to be examined to verify whether or not
 * it could be a valid IP address.
 * @return <code>true</code> if the string is a value that is a valid IP address,
 *  <code>false</code> otherwise.
 */
 public static boolean isIpAddress(String ipAddress) {

Matcher m1 = Utilities.VALID_IPV4_PATTERN.matcher(ipAddress);
if (m1.matches()) {
  return true;
}
Matcher m2 = Utilities.VALID_IPV6_PATTERN.matcher(ipAddress);
return m2.matches();
  }


}

0
投票

The IPAddress Java library支持以多态方式解析IPv4和IPv6 CIDR子网(即地址/前缀格式)。免责声明:我是项目经理。

以下方法是用于验证的示例代码:

static void parse(String str) {
    IPAddressString addrString = new IPAddressString(str);
    try {
         IPAddress addr = addrString.toAddress();
         IPAddress hostAddr = addrString.toHostAddress();
         Integer prefix = addr.getNetworkPrefixLength();
         if(prefix == null) {
             System.out.println(addr + " has no prefix length"); 
         } else {
             System.out.println(addr + " has host address " + hostAddr + " and prefix length " + prefix);
         }
    } catch(AddressStringException e) {
        System.out.println(addrString + " is invalid: " + e.getMessage());
    }
}

使用问题中提供的示例,上述方法的输出是:

abcd:ef01:2345:6789:abcd:ef01:2345:6789 has no prefix length
2001:db8::8:800:200c:417a has no prefix length
ff01::101 has no prefix length
::1 has no prefix length
:: has no prefix length
2001:db8::8:800:200c:417a has no prefix length
ff01::101 has no prefix length
::1 has no prefix length
:: has no prefix length
::d01:4403 has no prefix length
::ffff:8190:3426 has no prefix length
::d01:4403 has no prefix length
FFFF:129.144.52.38 is invalid: FFFF:129.144.52.38 IP Address error: address has too few segments
2001:db8:0:cd30::/60 has host address 2001:db8:0:cd30:: and prefix length 60
2001:db8:0:cd30::/60 has host address 2001:db8:0:cd30:: and prefix length 60
2001:db8:0:cd30::/60 has host address 2001:db8:0:cd30:: and prefix length 60
2001:0DB8:0:CD3/60 is invalid: 2001:0DB8:0:CD3/60 IP Address error: address has too few segments
2001:db8::cd30/60 has host address 2001:db8::cd30 and prefix length 60
2001:db8::cd3/60 has host address 2001:db8::cd3 and prefix length 60

正如你所看到的,关于FFFF的问题是不正确的:129.144.52.38是有效的,关于2001:db8 :: cd30 / 60和2001:db8 :: cd3 / 60无效。第一个如果是:: FFFF:129.144.52.38则有效

© www.soinside.com 2019 - 2024. All rights reserved.