我对Guava的InetAddress.coerceToInteger方法有疑问。
根据文件的方法:
public static int coerceToInteger(InetAddress ip)
'返回表示IPv4地址的整数,无论提供的参数是否为IPv4地址。 “
但是,IPv4范围是无符号的32位,而Java的int是有符号的 - 意味着返回的值只能覆盖相关IPv4范围的一半。
我是否错过了某人或方法中存在实际问题?
由于
答案 0 :(得分:8)
32位值是32位值,无论是有符号还是无符号,它都可以有2 ^ 32个值。如果您的地址为192.168.0.1,则为负数,不会丢失任何信息。如果将其转换为字节(也是有符号的),则不会丢失任何信息。
BTW:对于IPv4地址,您可以使用此技巧
int address = ip.hashCode();
要将32位有符号值视为32位无符号值,您可以
int address32 = ...
long address = address32 & 0xFFFFFFFFL;
但是,在大多数情况下,您不需要这样做。
答案 1 :(得分:2)
我认为Javadoc包含答案:
IPv6地址在转换为IPv4地址之前被强制转换为IPv4地址 整数。
只要有应用程序假定所有IP地址 是IPv4地址,因此可以安全地转换为整数 (无论用于何种目的)此功能可用于处理IPv6 也可以在应用程序得到适当修复之前解决。
注意:强制转换为IPv4地址的IPv6地址只能用于 初步识别或索引等目的 真正的InetAddresses的集合。它们不能用作真实的 用于网络通信的地址。
换句话说,如果您提供IPv6地址,请不要指望它是实际可用的地址。准备好在代码或网络中处理具有特殊条件的强制地址。在我看来,文档可以从一个例子中受益匪浅。
答案 2 :(得分:0)
Java中的long是64位值,IPv4地址只是32位值。挑战在于Java没有无符号数据类型,因此读取无符号值需要一些魔术,通常是通过上转换为long。番石榴也有这个涵盖:
InetAddress addr = InetAddress.getLocalHost();
long ip = UnsignedInts.toLong (InetAddresses.coerceToInteger (addr));