【问题标题】:guava - InetAddress.coerceToInteger returns int instead of long番石榴 - InetAddress.coerceToInteger 返回 int 而不是 long
【发布时间】:2012-12-24 21:10:31
【问题描述】:

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

根据文档方法:

public static int coerceToInteger(InetAddress ip)

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

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

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

谢谢

【问题讨论】:

    标签: java guava inetaddress


    【解决方案1】:

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

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

    int address = ip.hashCode();
    

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

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

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

    【讨论】:

    • 谢谢彼得。明白了。我想我会在我的 java 代码中将它用作 int 并在插入 DB 之前(作为无符号 int)我将使用十六进制值的技巧。但我不明白你关于 IPv4 的 hashCode 的观点。你能扩展你的解释吗?
    • 这个数据结构在内部将地址存储为int,当你请求 hashCode() 时,它恰好给你这个值。我本来希望有一个像getAddress() 这样的方法,它被定义为获取这个值,但它恰好在这种情况下工作。
    • 好的,得到了​​ InetAddress 类中的 hashCode 点。但是,正如 here 所说,这不能保证。
    • 这就是为什么做同样事情但得到保证的方法会更好。
    【解决方案2】:

    我认为 Javadoc 包含答案:

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

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

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

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

    【讨论】:

      【解决方案3】:

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

      InetAddress addr = InetAddress.getLocalHost();
      long ip = UnsignedInts.toLong (InetAddresses.coerceToInteger (addr));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-04
        • 1970-01-01
        • 1970-01-01
        • 2013-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多