我之前已经问过类似的问题,但我还没有找到一个似乎有效的具体答案。我基本上试图编写一个函数,它将获取一个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"然后它运作正常。
答案 0 :(得分:1)
问题出在这里
BigInteger n = new BigInteger(InetAddress.getByName(sIPv6).getAddress());
byte[] bytes = n.toByteArray();
当您调用toByteArray()
时,返回的数组仅足以包含地址的所有有效位。由于您的地址以0:0:...
开头,因此返回的字节数组太短(14)。你必须用二进制零左边填充它,使其长128位(16字节)。
答案 1 :(得分:0)
上述答案是正确的,但并不完整。除了所描述的左填充之外,当你有17个字节时,你还必须偶尔删除最高字节,对于最高字节中8xxx到fxxx的地址,这可能会发生,如下面的答案所述:IPv6 ip (fc00::) addr is of illegal length
换句话说,您必须扩展或缩小到恰好16个字节。