4

我对 Guava 的InetAddress.coerceToInteger方法有疑问。

根据文档的方法:

公共静态 int coerceToInteger(InetAddress ip)

'无论提供的参数是否为 IPv4 地址,都返回一个表示 IPv4 地址的整数。'

但是,IPv4 范围是无符号的 32 位,而 Java 的 int 是有符号的 - 意味着返回的值只能覆盖 IPv4 相关范围的一半。

我错过了某人还是该方法存在真正的问题?

谢谢

4

3 回答 3

8

32 位值是 32 位值,无论是有符号还是无符号,它都可以有 2^32 个值。如果您有一个像 192.168.0.1 这样的地址,它将是一个负数,不会丢失任何信息。如果将其转换为字节(也有符号),则不会丢失任何信息。

顺便说一句:对于 IPv4 地址,您可以使用此技巧

int address = ip.hashCode();

要将 32 位有符号值视为 32 位无符号值,您可以

int address32 = ...
long address = address32 & 0xFFFFFFFFL;

但是,在大多数情况下,您不需要这样做。

于 2013-01-10T13:08:14.577 回答
2

我认为 Javadoc 包含答案:

IPv6 地址在转换为整数之前被强制转换为 IPv4 地址。

只要有应用程序假定所有 IP 地址都是 IPv4 地址,因此可以安全地转换为整数(无论出于何种目的),此函数也可用于处理 IPv6 地址,直到应用程序得到适当修复。

注意:强制转换为 IPv4 地址的 IPv6 地址只能用于基本识别或索引到真实 InetAddresses 集合的目的。它们不能用作网络通信的真实地址。

换句话说,如果您提供 IPv6 地址,不要期望它是实际可用的地址。准备好在您的代码或网络中处理具有特殊条件的强制地址。在我看来,文档可以从一个例子中受益匪浅。

于 2013-01-10T13:10:59.827 回答
0

Java 中的 long 是 64 位值,IPv4 地址只有 32 位值。挑战在于 Java 没有无符号数据类型,因此需要一些魔法来读取无符号值,通常是通过上转换为长整数。番石榴也涵盖了这一点:

InetAddress addr = InetAddress.getLocalHost();
long ip = UnsignedInts.toLong (InetAddresses.coerceToInteger (addr));
于 2016-06-15T00:25:48.420 回答