Java中IPV6地址转换成压缩形式
我使用 Inet6Address.getByName("2001:db8:0:0:0:0:2:1").toString()
方法来压缩 IPv6 地址,输出为 2001 :db8:0:0:0:0:2:1
,但我需要 2001:db8::2:1
。 ,基本上压缩输出应该基于 RFC 5952 标准 ,即
< a href="https://www.rfc-editor.org/rfc/rfc5952#section-4.2.1" rel="nofollow noreferrer">尽可能缩短:例如,2001:db8:0:0:0:0:2:1 必须缩短为
2001:db8::2:1。同样,2001:db8::0:1 也是不可接受的, 因为符号“::”可以用来产生 较短的表示形式 2001:db8::1。处理一个 16 位 0 字段 :符号“::”不得仅用于缩短一个 16 位 0 字段。 例如,表示 2001:db8:0:1:1:1:1:1 是正确的,但是 2001:db8::1:1:1:1:1 不正确。
选择“::”的位置 : = 当“::”的位置有替代选择时, 连续 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 是正确的 代表。
我还检查了另一个发布在堆栈溢出中,但没有指定条件(例如选择 :: 的位置)。
有没有java库可以处理这个问题?有人可以帮我吗?
提前致谢。
I have used Inet6Address.getByName("2001:db8:0:0:0:0:2:1").toString()
method to compress IPv6 address, and the output is 2001:db8:0:0:0:0:2:1
,but i need 2001:db8::2:1
. , Basically the compression output should based on RFC 5952 standard , that is
Shorten as Much as Possible : 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.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.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.
I have also checked another post in Stack overflow, but there was no condition specified (example choice in placement of ::).
Is there any java library to handle this? Could anyone please help me?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这个怎么样?
没有 Java 双反斜杠地狱的解释:
输入:
输出:(
我希望最后一个示例是正确的 - 或者如果地址以
0
结尾,是否还有其他规则?)How about this?
Explanation without Java double-backslash hell:
Input:
Output:
(I hope the last example is correct - or is there another rule if the address ends in
0
?)我最近遇到了同样的问题,并且想(非常轻微地)改进蒂姆的答案。
以下正则表达式有两个优点:
((?:(?:^|:)0+\\b){2,}):?(?!\\S*\\b\\1:0 +\\b)(\\S*)
首先,它合并了匹配多个零的更改。其次,它还可以正确匹配最长的零链位于地址开头的地址(例如
0:0:0:0:0:0:0:1
)。I recently ran into the same problem and would like to (very slightly) improve on Tim's answer.
The following regular expression offers two advantages:
((?:(?:^|:)0+\\b){2,}):?(?!\\S*\\b\\1:0+\\b)(\\S*)
Firstly, it incorporates the change to match multiple zeroes. Secondly, it also correctly matches addresses where the longest chain of zeroes is at the beginning of the address (such as
0:0:0:0:0:0:0:1
).Guava 的
InetAddresses
类具有 toAddrString() 其格式根据 RFC 5952。Guava's
InetAddresses
class has toAddrString() which formats according to RFC 5952.java-ipv6 几乎就是你想要的。从版本 0.10 开始,它不会检查用 :: 缩短的最长的零串 - 例如 0:0:1:: 被缩短为 ::1:0:0:0:0:0。不过,对于处理 IPv6 地址来说,它是一个非常不错的库,这个问题应该是 已在版本 0.11 中修复,因此该库为 符合 RFC 5952 。
java-ipv6 is almost what you want. As of version 0.10 it does not check for the longest run of zeroes to shorten with :: - for instance 0:0:1:: is shortened to ::1:0:0:0:0:0. It is a very decent library for the handling of IPv6 addresses, though, and this problem should be fixed with version 0.11, such that the library is RFC 5952 compliant.
开源 IPAddress Java 库 可以按照描述执行,它提供了多种为 IPv4 生成字符串的方法和/或 IPv6,包括 IPv6 与 rfc 5952 匹配的规范字符串。免责声明:我是该库的项目经理。
使用您列出的示例,示例代码为:
The open-source IPAddress Java library can do as described, it provides numerous ways of producing strings for IPv4 and/or IPv6, including the canonical string which for IPv6 matches rfc 5952. Disclaimer: I am the project manager of that library.
Using the examples you list, sample code is:
不太优雅,但这是我的建议(基于chrixm工作):
结果:
7469:125f:8eb6:94dd:e53f:cfe7:61a9:8351 ->
7469:125f:8eb6:94dd:e53f:cfe7:61a9:8351
7469:125f:0000:0000:e53f:cfe7:0000:0000 -> 7469:125f::e53f:cfe7:0:0
7469:125f:0000:0000:000f:c000:0000:0000 -> 7469:125f::f:c000:0:0
7469:125f:0000:0000:000f:c000:0000:0000 -> 7469:125f::f:c000:0:0
7469:0000:0000:94dd:0000:0000:0000:8351 -> 7469:0:0:94dd::8351
0469:125f:8eb6:94dd:0000:cfe7:61a9:8351 ->
469:125f:8eb6:94dd:0:cfe7:61a9:8351
0069:125f:8eb6:94dd:0000:cfe7:61a9:8351 ->
69:125f:8eb6:94dd:0:cfe7:61a9:8351
0009:125f:8eb6:94dd:0000:cfe7:61a9:8351 ->
9:125f:8eb6:94dd:0:cfe7:61a9:8351
0000:0000:8eb6:94dd:e53f:0007:6009:8350 ->
::8eb6:94dd:e53f:7:6009:8350 0000:0000:8eb6:94dd:e53f:0007:6009:8300
-> ::8eb6:94dd:e53f:7:6009:8300 0000:0000:8eb6:94dd:e53f:0007:6009:8000 ->
::8eb6:94dd:e53f:7:6009:8000 7469:0000:0000:0000:e53f:0000:0000:8300
-> 7469::e53f:0:0:8300 7009:100f:8eb6:94dd:e000:cfe7:6009:8351 -> 7009:100f:8eb6:94dd:e000:cfe7:6009:8351
7469:100f:8006:900d:e53f:cfe7:61a9:8351 ->
7469:100f:8006:900d:e53f:cfe7:61a9:8351
7000:1200:8e00:94dd:e53f:cfe7:0000:0001 ->
7000:1200:8e00:94dd:e53f:cfe7:0:1
0000:0000:0000:0000:0000:0000:0000:0000 -> ::
0000:0000:0000:94dd:0000:0000:0000:0000 -> 0:0:0:94dd::
0000:1200:0000:0000:0000:0000:0000:0000 -> 0:1200::
0000:0000:0000:1200:0000:0000:0000:8351 -> ::1200:0:0:0:8351
0000:125f:0000:94dd:e53f:0000:61a9:0000 ->
0:125f:0:94dd:e53f:0:61a9:0 7469:0000:8eb6:0000:e53f:0000:61a9:0000
-> 7469:0:8eb6:0:e53f:0:61a9:0 0000:125f:0000:94dd:0000:cfe7:0000:8351 ->
0:125f:0:94dd:0:cfe7:0:8351 0000:025f:0000:94dd:0000:cfe7:0000:8351
-> 0:25f:0:94dd:0:cfe7:0:8351 0000:005f:0000:94dd:0000:cfe7:0000:8351 -> 0:5f:0:94dd:0:cfe7:0:8351
0000:000f:0000:94dd:0000:cfe7:0000:8351 -> 0:f:0:94dd:0:cfe7:0:8351
0000:0000:0000:0000:0000:0000:0000:0001 -> ::1
Not quite elegant but this is my proposal (based on chrixm work):
results:
7469:125f:8eb6:94dd:e53f:cfe7:61a9:8351 ->
7469:125f:8eb6:94dd:e53f:cfe7:61a9:8351
7469:125f:0000:0000:e53f:cfe7:0000:0000 -> 7469:125f::e53f:cfe7:0:0
7469:125f:0000:0000:000f:c000:0000:0000 -> 7469:125f::f:c000:0:0
7469:125f:0000:0000:000f:c000:0000:0000 -> 7469:125f::f:c000:0:0
7469:0000:0000:94dd:0000:0000:0000:8351 -> 7469:0:0:94dd::8351
0469:125f:8eb6:94dd:0000:cfe7:61a9:8351 ->
469:125f:8eb6:94dd:0:cfe7:61a9:8351
0069:125f:8eb6:94dd:0000:cfe7:61a9:8351 ->
69:125f:8eb6:94dd:0:cfe7:61a9:8351
0009:125f:8eb6:94dd:0000:cfe7:61a9:8351 ->
9:125f:8eb6:94dd:0:cfe7:61a9:8351
0000:0000:8eb6:94dd:e53f:0007:6009:8350 ->
::8eb6:94dd:e53f:7:6009:8350 0000:0000:8eb6:94dd:e53f:0007:6009:8300
-> ::8eb6:94dd:e53f:7:6009:8300 0000:0000:8eb6:94dd:e53f:0007:6009:8000 ->
::8eb6:94dd:e53f:7:6009:8000 7469:0000:0000:0000:e53f:0000:0000:8300
-> 7469::e53f:0:0:8300 7009:100f:8eb6:94dd:e000:cfe7:6009:8351 -> 7009:100f:8eb6:94dd:e000:cfe7:6009:8351
7469:100f:8006:900d:e53f:cfe7:61a9:8351 ->
7469:100f:8006:900d:e53f:cfe7:61a9:8351
7000:1200:8e00:94dd:e53f:cfe7:0000:0001 ->
7000:1200:8e00:94dd:e53f:cfe7:0:1
0000:0000:0000:0000:0000:0000:0000:0000 -> ::
0000:0000:0000:94dd:0000:0000:0000:0000 -> 0:0:0:94dd::
0000:1200:0000:0000:0000:0000:0000:0000 -> 0:1200::
0000:0000:0000:1200:0000:0000:0000:8351 -> ::1200:0:0:0:8351
0000:125f:0000:94dd:e53f:0000:61a9:0000 ->
0:125f:0:94dd:e53f:0:61a9:0 7469:0000:8eb6:0000:e53f:0000:61a9:0000
-> 7469:0:8eb6:0:e53f:0:61a9:0 0000:125f:0000:94dd:0000:cfe7:0000:8351 ->
0:125f:0:94dd:0:cfe7:0:8351 0000:025f:0000:94dd:0000:cfe7:0000:8351
-> 0:25f:0:94dd:0:cfe7:0:8351 0000:005f:0000:94dd:0000:cfe7:0000:8351 -> 0:5f:0:94dd:0:cfe7:0:8351
0000:000f:0000:94dd:0000:cfe7:0000:8351 -> 0:f:0:94dd:0:cfe7:0:8351
0000:0000:0000:0000:0000:0000:0000:0001 -> ::1
执行一些测试后,我认为以下内容捕获了所有不同的 IPv6 场景:
After performing some tests, I think the following captures all the different IPv6 scenarios: