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 字节)。

于 2014-05-30T20:05:44.367 回答
0

上面的答案是正确的,但并不完整。除了所描述的左填充之外,当您有 17 个字节时,您还必须偶尔删除最高字节,这可能发生在最高字节中具有 8xxx 到 fxxx 的地址中,如本答案所述:IPv6 ip (fc00::) addr 的长度非法

换句话说,您必须扩展或收缩到恰好 16 个字节。

于 2016-09-09T07:41:28.507 回答