将 IPv4 映射的 IPv6 转换为字节字符串

问题描述 投票:0回答:1

我想将下面类似的IPv4映射的IPv6地址转换为字节字符串以存储在java中的protobuf中:

    "::ffff:129.144.52.38",
    "::ffff:100.10.1.0",
    "::192.168.115.53" 
]

我使用以下代码进行此转换:

com.googlecode.ipv6.IPv6Address ipv6Address = com.googlecode.ipv6.IPv6Address.fromString(iPv6Str); com.google.protobuf.ByteString byteString = ByteString.copyFrom(ipv6Address.toByteArray()); 
当我使用以下方法将其转换回来时:
com.googlecode.ipv6.IPv6Address ipv6Address = com.googlecode.ipv6.IPv6Address.fromByteArray(byteString.toByteArray()); ip = ipv6Address.toString();

对于以下IP: "::192.168.115.53" -----> 这被转换为其等效的 ipv6 "::c0a8:7335" 然而 “::ffff:129.144.52.38”被转换回其原始格式。

观察到,对于前面带有 ffff 的 IPv4 映射的 IPv6,格式没有改变。 但是当 IPv4 映射的 IPv6 前面带有 :: (0000) 时,格式将转换为 IPv6。

我想保持原来的格式而不改变它,这样从protobuf读回IP ::192.168.115.53后就可以按原样返回。这可能吗?

这是谷歌库(ipv6 / protobuf)转换中的错误吗?不确定在哪一部分将其转换为 IPv6 等效项。

我已经尝试了上面的代码,我没有任何解决方案

java type-conversion ipv6 ipv4 bytestring
1个回答
0
投票

“...我想将下面类似的 IPv4 映射 IPv6 地址转换为字节字符串...”

您可以使用静态 InetAddress#getByName 方法将值解析为 InetAddress 对象。

InetAddress ip = InetAddress.getByName("::192.168.115.53");

可以通过 InetAddress#getAddress 方法获得字节数组

byte[] bytes = ip.getAddress();

这是一个例子。

String[] strings = {
    "::ffff:129.144.52.38",
    "::ffff:100.10.1.0",
    "::192.168.115.53"
};
InetAddress ip;
byte[] b;
for (String s : strings) {
    b = (ip = InetAddress.getByName(s)).getAddress();
    System.out.printf("%s, %s%n", ip, Arrays.toString(b));
}

输出

/129.144.52.38, [-127, -112, 52, 38]
/100.10.1.0, [100, 10, 1, 0]
/0:0:0:0:0:0:c0a8:7335, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -64, -88, 115, 53]

"... 对于以下 ip: "::192.168.115.53" -----> 这将转换为其等效的 ipv6 "::c0a8:7335" 其中 "::ffff:129.144.52.38" 是转换回原来的格式。

观察到,对于前面带有 ffff 的 IPv4 映射的 IPv6,格式没有改变。但是,当 IPv4 映射的 IPv6 前面带有 :: (0000) 时,格式将转换为 IPv6。 ...

...这是谷歌库(ipv6 / protobuf)转换中的错误吗?不确定这会在哪一部分转换为 IPv6 等效项。”

这是相关的维基百科文章。

维基百科 – IPv6 地址 – Transition_from_IPv4

从 IPv4 过渡
::ffff:0:0/96 — 此前缀用于 IPv6 转换机制,并指定为 IPv4 映射的 IPv6 地址。 ...

如果您想获取 address 的最后 4 个字节,只需使用 System#arraycopy 方法。

byte[] b, b1 = new byte[4];
b = InetAddress.getByName("::192.168.115.53").getAddress();
System.arraycopy(b, b.length - 4, b1, 0, 4);

如果您想要获取十六进制值序列,请使用以下内容,而不是字节数组

StringBuilder s = new StringBuilder();
for (byte b : bytes) s.append("%02x".formatted(b));

输出

81903426
640a0100
c0a87335
© www.soinside.com 2019 - 2024. All rights reserved.