IPv6 验证

发布于 2024-11-06 19:46:49 字数 968 浏览 6 评论 0原文

我使用 IPAddressUtil.isIPv6LiteralAddress (ipAddress) 方法来验证 IPv6,但此方法对于 ipv6-address/prefix-length 格式失败(格式在 RFC 4291 第 2.3 节) IPV6。

有人知道验证“ ipv6-address/prefix-length ”格式的验证器吗?

IPV6的法律表示

  1. ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
  2. 2001:DB8:0:0:8:800:200C: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

< strong>不是 IPV6 的法律代表

  1. 2001:0DB8:0:CD3/60
  2. 2001:0DB8::CD30/60
  3. 2001:0DB8::CD3/60

I used IPAddressUtil.isIPv6LiteralAddress (ipAddress) method to validate IPv6, but this method fails for ipv6-address/prefix-length format (format is mentioned in RFC 4291 section 2.3) of IPV6.

Could anyone know any validators which validate " ipv6-address/prefix-length " format?

Legal representations of IPV6

  1. ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
  2. 2001:DB8:0:0:8:800:200C: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

NOT legal representations of IPV6

  1. 2001:0DB8:0:CD3/60
  2. 2001:0DB8::CD30/60
  3. 2001:0DB8::CD3/60

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

水中月 2024-11-13 19:46:49

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


isInetAddress

public static boolean isInetAddress(String ipString)

如果提供的字符串是有效的 IP 字符串文字,则返回 true,否则返回 false。

参数ipString - 要计算为 IP 字符串文字的字符串

返回true(如果参数是有效 IP)字符串文字

You can use the Guava library, specifically using the com.google.common.net.InetAddresses class, calling isInetAddress().


isInetAddress

public static boolean isInetAddress(String ipString)

Returns true if the supplied string is a valid IP string literal, false otherwise.

Parameters: ipString - String to evaluated as an IP string literal

Returns: true if the argument is a valid IP string literal

生寂 2024-11-13 19:46:49

IPAddress Java 库 支持以 a 格式解析 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 则有效

The IPAddress Java library supports parsing both IPv4 and IPv6 CIDR subnets (ie address/prefix format) in a polymorphic manner. Disclaimer: I am the project manager.

The following method is example code for validating:

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());
    }
}

Using the examples provided in the question, the output of the above method is:

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

As you can see, the question was incorrect about FFFF:129.144.52.38 being valid and about 2001:db8::cd30/60 and 2001:db8::cd3/60 being invalid. The first one would be valid if it were ::FFFF:129.144.52.38

猫弦 2024-11-13 19:46:49

看看这是否有效:

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} 是我添加到正则表达式中以匹配您的示例的内容。

See if this works:

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
}

I purchased a very helpful program called RegexMagic nearly a year ago for some complicated regular expressions I planned on using.

This was suppose to be Java, so it should compile, I assume the /60 can be between the ranges of 0000 and FFFF you can modify that last part.

/[A-F0-9]{0,4} is what I added to the regular expression to match your example.

情绪 2024-11-13 19:46:49

我的想法是把它分成两部分,前缀地址和前缀len。

<强>1。验证前缀地址使用一些正则表达式来验证 IPv6 地址
2.验证前缀 len 必须是整数
3.前缀地址中的 ':' 只能小于前缀 len 除以 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;
    }

My idea is to split it into two part, prefix address and prefix len.

1. validate prefix address use the some regex to validate IPv6 address
2. validate the prefix len that must be an integer
3. prefix address can only have ':' s less than the result ofprefix len divided by 16
4. other logic must be considered as well, leave TODOs here, sorry:(

  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;
    }
北渚 2024-11-13 19:46:49

严格来说,2.3节描述的不是地址表示,而是地址前缀的表示(即使是“全长”前缀也与地址不同)。

IPv6 地址前缀是
用符号表示:
ipv6 地址/前缀长度
在哪里
ipv6-address 是采用列出的任何表示法的 IPv6 地址
在第 2.2 节中。

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

Strictly speaking, a section 2.3 does not describe an address representation, but a representation of address prefix (even the "full-length" prefix is not the same as an address).

An IPv6 address prefix is
represented by the notation:
ipv6-address/prefix-length
where
ipv6-address is an IPv6 address in any of the notations listed
in Section 2.2.

That means you may safely disregard this format if you need to validate addresses.

落花浅忆 2024-11-13 19:46:49

我在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();
  }


}

I had tried below regex in java and it worked for IPV4 and 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();
  }


}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文