1

以前にも同様の質問があったことは知っていますが、うまくいくと思われる特定の回答を見つけることができませんでした。私は基本的に、IPv6 アドレスを取得し、それに任意の数の IP アドレスを追加または削除する関数を作成しようとしています。

一部のIPv6アドレスでは機能するが、他のアドレスでは機能しないため、バイト順序で問題が発生していると思います。ただし、行き詰まっているため、問題を解決しようとする際に助けが必要です。

問題を示す SSCCE を以下に示します。これは基本的に InetAddress から BigInteger に変換し、再び元に戻します。アイデアは、途中で BigInteger から加算または減算を実行することです。

import java.math.*;
import java.net.*;

public class SSCCE {
  public static void main(String[] args) {
    String sIPv6 = "::00D3:0:2F3B:02AA:00FF:0";

    try {
      BigInteger n = new BigInteger(InetAddress.getByName(sIPv6).getAddress());
      byte[] bytes = n.toByteArray();

      System.out.println("Original = " + sIPv6);
      System.out.println("New = " + InetAddress.getByAddress(bytes).getHostAddress());
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

これを実行すると、次の出力が得られます。

Original = ::00D3:0:2F3B:02AA:00FF:0
java.net.UnknownHostException: addr is of illegal length
        at java.net.InetAddress.getByAddress(Unknown Source)
        at java.net.InetAddress.getByAddress(Unknown Source)
        at SSCCE.main(SSCCE.java:12)

ただし、IPv6 アドレスを「2001::00D3:0:2F3B:02AA:00FF:0」に変更すると、正常に動作します。

4

2 に答える 2

1

問題はここにあります

  BigInteger n = new BigInteger(InetAddress.getByName(sIPv6).getAddress());
  byte[] bytes = n.toByteArray();

呼び出しtoByteArray()たときに返される配列は、アドレスのすべての有効ビットを含むのに十分な大きさです。アドレスが0:0:...返されたバイト配列で始まるため、短すぎます (14)。128 ビット長 (16 バイト) にするには、左に 2 進ゼロを埋め込む必要があります。

于 2014-05-30T20:05:44.367 に答える
0

上記の答えは正しいですが、完全ではありません。説明されている左側のパディングに加えて、17 バイトの場合は最上位バイトも削除する必要があります。これは、この回答で説明されているように、最上位バイトが 8xxx から fxxx までのアドレスで発生する可能性があります: IPv6 ip (fc00::) addr の長さが不正です

つまり、正確に 16 バイトに拡張または縮小する必要があります。

于 2016-09-09T07:41:28.507 に答える