4

GuavaのInetAddress.coerceToIntegerメソッドについて質問があります。

ドキュメントによると、方法は次のとおりです。

public static 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 には符号なしのデータ型がないため、通常は long にアップコンバートすることによって、符号なしの値を読み取るためにいくつかの魔法が必要になることです。グアバもこれをカバーしています:

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