Inet6Address对无效的IPv6地址有效 [英] Inet6Address valid for invalid IPv6 Address

查看:197
本文介绍了Inet6Address对无效的IPv6地址有效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用java.net.Inet6Address来验证输入字符串是否为有效的 IPv6地址.

这是我的代码段:

public static boolean isValidIPv6ddress(String address) {
    if (address.isEmpty()) {
        return false;
    }
    try {
        Object res = InetAddress.getByName(address);
        return res instanceof Inet6Address;
    } catch (final UnknownHostException ex) {
        return false;
    }
}

不幸的是,即使以下输入无效,上述方法也返回true:

System.out.println(isValidIPv6ddress("2A00:17C8:50C:0000:0000:0000:0000:00001"));
System.out.println(isValidIPv6ddress("2A00:17C8:50C:0000:0000:00000000000000:0000:00001"));
System.out.println(isValidIPv6ddress("2A00:17C8:50C:00001235:0000:00000000000000:0000:00001"));

API是否忽略前导零?还是API中有 bug ?

解决方案

基于有关IPv6地址有效文本表示形式的最新RFC,您遇到了错误或对IPv6地址文本表示形式的解释不佳.用于IPv6地址架构的最新RFC是 RFC 4291,IP版本6寻址架构 . RFC具有第2.2节.地址的文本表示形式说(请注意,该限制为四个十六进制数字):

2.2.地址的文字表示

将IPv6地址表示为以下三种常规形式 文字字符串:

  1. 首选格式为x:x:x:x:x:x:x:x,其中'x'是 地址的八个16位部分中的四个十六进制数字. 例子:

     ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
    
     2001:DB8:0:0:8:800:200C:417A
    

    请注意,不必在 单个字段,但每个字段中至少必须有一个数字 字段(第2节中所述的情况除外).

  2. 由于某些分配某些样式的IPv6的方法 地址,通常包含长字符串的地址 零位.为了使写地址包含零 容易一点,有一种特殊的语法可以压缩零. "::"的使用表示一组或多组16位零. "::"在一个地址中只能出现一次. "::"也可以是 用于压缩地址中的前导零或尾随零.

    例如,以下地址

     2001:DB8:0:0:8:800:200C:417A   a unicast address
     FF01:0:0:0:0:0:0:101           a multicast address
     0:0:0:0:0:0:0:1                the loopback address
     0:0:0:0:0:0:0:0                the unspecified address
    

    可以表示为

     2001:DB8::8:800:200C:417A      a unicast address
     FF01::101                      a multicast address
     ::1                            the loopback address
     ::                             the unspecified address
    

  3. 另一种形式,有时在处理时更方便 IPv4和IPv6节点的混合环境是 x:x:x:x:x:x:d.d.d.d,其中"x"是的十六进制值 地址的六个高阶16位元和'd'是 四个低阶8位元的十进制值 地址(标准IPv4表示形式).例子:

     0:0:0:0:0:0:13.1.68.3
     0:0:0:0:0:FFFF:129.144.52.38
    

    或压缩形式:

     ::13.1.68.3
     ::FFFF:129.144.52.38
    

由于RFC 4291要求每个16位字段不得超过四个十六进制字符,因此认为在16位字段中具有四个以上十六进制字符的任何IPv6地址文本表示形式都是不正确的. /p>


RFC 4291由 RFC 5952(IPv6地址文本表示的建议)更新. ,这进一步限制了 4.1节中的适当表示.将16位字段中的前导零处理为无前导零:

4.1.处理16位字段中的前导零

必须抑制前导零.例如,2001:0db8 :: 0001是 不可接受,必须将其表示为2001:db8 :: 1.单个16位0000字段必须表示为0.

RFC 5952还要求压缩格式,其中必须将多个连续的16位字段压缩为:::

4.2. "::"用法

4.2.1.尽可能缩短

必须最大限度地使用符号"::". 例如,必须将2001:db8:0:0:0:0:2:1缩短为2001:db8 :: 2:1. 同样,也不接受2001:db8 :: 0:1,因为符号"::" 本可以用来产生较短的表示形式2001:db8 :: 1.

4.2.2.处理一个16位0字段

符号"::"绝不能用于缩短一个16位0 场地.例如,表示形式2001:db8:0:1:1:1:1:1是 正确,但是2001:db8 :: 1:1:1:1:1不正确.

4.2.3.选择"::"的位置

如果在"::"的位置上有其他选择,则 必须缩短连续的16位0字段的最长运行时间(即, 具有三个连续零字段的序列在2001年缩短了: 0:0:1:0:0:0:1).当连续的16位0字段的长度 等于(即2001:db8:0:0:1:0:0:1),第一个零序列 位必须缩短.例如,2001:db8 :: 1:0:0:1是正确的 表示形式.

基本上,RFC 5952还要求您接受任何有效的RFC 4291格式,但是您应该仅输出任何RFC 5952格式的IPv6文本表示形式:

  1. IPv6文本表示的建议

    有关IPv6规范文本表示格式的建议 地址在本节中介绍.在这里的推荐 该文档是完全符合[RFC4291]的文档,由 各种操作系统,并且对人类友好.推荐 在本节中,当生成一个 地址以文本表示,但所有实现都必须 接受并能够处理任何合法的[RFC4291]格式.它是 建议人们在拼写时也遵循这些建议 地址.

I'm using java.net.Inet6Address to validate if an input string is a valid IPv6 address or not.

Here is my code snippet:

public static boolean isValidIPv6ddress(String address) {
    if (address.isEmpty()) {
        return false;
    }
    try {
        Object res = InetAddress.getByName(address);
        return res instanceof Inet6Address;
    } catch (final UnknownHostException ex) {
        return false;
    }
}

Unfortunately the above method returns true even for the following inputs which are invalid:

System.out.println(isValidIPv6ddress("2A00:17C8:50C:0000:0000:0000:0000:00001"));
System.out.println(isValidIPv6ddress("2A00:17C8:50C:0000:0000:00000000000000:0000:00001"));
System.out.println(isValidIPv6ddress("2A00:17C8:50C:00001235:0000:00000000000000:0000:00001"));

Does the API ignore leading zeroes? Or is there a bug in the API?

解决方案

Based on the most current RFCs regarding the valid text representations of IPv6 addresses, you have encountered a bug, or a poor interpretation of IPv6 address text representation. The most current RFC for IPv6 address architecture is RFC 4291, IP Version 6 Addressing Architecture. That RFC has Section 2.2. Text Representation of Addresses that says (note that the limit is four hexadecimal digits):

2.2. Text Representation of Addresses

There are three conventional forms for representing IPv6 addresses as text strings:

  1. The preferred form is x:x:x:x:x:x:x:x, where the 'x's are one to four hexadecimal digits of the eight 16-bit pieces of the address. Examples:

     ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
    
     2001:DB8:0:0:8:800:200C:417A
    

    Note that it is not necessary to write the leading zeros in an individual field, but there must be at least one numeral in every field (except for the case described in 2.).

  2. Due to some methods of allocating certain styles of IPv6 addresses, it will be common for addresses to contain long strings of zero bits. In order to make writing addresses containing zero bits easier, a special syntax is available to compress the zeros. The use of "::" indicates one or more groups of 16 bits of zeros. The "::" can only appear once in an address. The "::" can also be used to compress leading or trailing zeros in an address.

    For example, the following addresses

     2001:DB8:0:0:8:800:200C:417A   a unicast address
     FF01:0:0:0:0:0:0:101           a multicast address
     0:0:0:0:0:0:0:1                the loopback address
     0:0:0:0:0:0:0:0                the unspecified address
    

    may be represented as

     2001:DB8::8:800:200C:417A      a unicast address
     FF01::101                      a multicast address
     ::1                            the loopback address
     ::                             the unspecified address
    

  3. An alternative form that is sometimes more convenient when dealing with a mixed environment of IPv4 and IPv6 nodes is x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values of the six high-order 16-bit pieces of the address, and the 'd's are the decimal values of the four low-order 8-bit pieces of the address (standard IPv4 representation). Examples:

     0:0:0:0:0:0:13.1.68.3
     0:0:0:0:0:FFFF:129.144.52.38
    

    or in compressed form:

     ::13.1.68.3
     ::FFFF:129.144.52.38
    

Since RFC 4291 demands that there be no more than four hexadecimal characters per 16-bit field, it would be incorrect to consider any IPv6 address text representation with more than four hexadecimal characters in a 16-bit field to be valid.


RFC 4291 was updated by RFC 5952, A Recommendation for IPv6 Address Text Representation, which further limited a proper representation in Section 4.1. Handling Leading Zeros in a 16-Bit Field to no leading zeros:

4.1. Handling Leading Zeros in a 16-Bit Field

Leading zeros MUST be suppressed. For example, 2001:0db8::0001 is not acceptable and must be represented as 2001:db8::1. A single 16-bit 0000 field MUST be represented as 0.

RFC 5952 Also requires the compressed format where more than one consecutive 16-bit field must be compressed to :::

4.2. "::" Usage

4.2.1. Shorten as Much as Possible

The use of the symbol "::" MUST be used to its maximum capability. For example, 2001:db8:0:0:0:0:2:1 must be shortened to 2001:db8::2:1. Likewise, 2001:db8::0:1 is not acceptable, because the symbol "::" could have been used to produce a shorter representation 2001:db8::1.

4.2.2. Handling One 16-Bit 0 Field

The symbol "::" MUST NOT be used to shorten just one 16-bit 0 field. For example, the representation 2001:db8:0:1:1:1:1:1 is correct, but 2001:db8::1:1:1:1:1 is not correct.

4.2.3. Choice in Placement of "::"

When there is an alternative choice in the placement of a "::", the longest run of consecutive 16-bit 0 fields MUST be shortened (i.e., the sequence with three consecutive zero fields is shortened in 2001: 0:0:1:0:0:0:1). When the length of the consecutive 16-bit 0 fields are equal (i.e., 2001:db8:0:0:1:0:0:1), the first sequence of zero bits MUST be shortened. For example, 2001:db8::1:0:0:1 is correct representation.

Basically, RFC 5952 is also requiring you to accept any valid RFC 4291 format, but you should only output any RFC 5952 formatted IPv6 text representation:

  1. A Recommendation for IPv6 Text Representation

    A recommendation for a canonical text representation format of IPv6 addresses is presented in this section. The recommendation in this document is one that complies fully with [RFC4291], is implemented by various operating systems, and is human friendly. The recommendation in this section SHOULD be followed by systems when generating an address to be represented as text, but all implementations MUST accept and be able to handle any legitimate [RFC4291] format. It is advised that humans also follow these recommendations when spelling an address.

这篇关于Inet6Address对无效的IPv6地址有效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆