问题
I am seeing the error while converting BigInteger to InetAddress. This happens only with a particular IP "fc00::". Here is my test code. Please let me know if I am missing something.
public class IPv6Test {
public static BigInteger ipv6ToNumber(InetAddress Inet6Address)
{
return new BigInteger(1,Inet6Address.getAddress());
}
public static void main(String[] args) throws UnknownHostException
{
InetAddress iaStart = InetAddress.getByName("fc00::");
BigInteger biStart = ipv6ToNumber(iaStart);
System.out.println(biStart.toString());
System.out.println(InetAddress.getByAddress(biStart.toByteArray()).getHostAddress()) ;
}
}
回答1:
The reason is that BigInteger is tacking on an extra byte in biStart.toByteArray();
It is giving you 17 bytes, which is too long, an IPv6 address is 16 bytes. The extra byte is at the high end, and it is 0.
If you do this in your code, then it works:
byte bytes[] = biStart.toByteArray();
if(bytes.length > 16) {
byte bytes2[] = new byte[16];
System.arraycopy(bytes, 1, bytes2, 0, bytes2.length);
bytes = bytes2;
}
If you read the javadoc for BigInteger.bitLength(), it indicates that the two's complement representation of the big integer will be at least bitLength() + 1 bits long. toByteArray() gives you the two's complement representation. Since you need all 128 bits to repesent this address, and you are talking on an extra bit, you end up with 17 bytes.
Why is there an extra byte? That is because your address is a positive number. But the highest byte is fc00, which in two's complement becomes a negative number. So there must be an extra 0 bit at the high end to keep the number positive in two's complement, and thus the two's complement representation takes 129 bits or 17 bytes, not 128 bits and 16 bytes. This will occur for any address with 1 in the very highest bit, or any address which starts with 8xxx to fxxx, such as fc00.
来源:https://stackoverflow.com/questions/28222896/ipv6-ip-fc00-addr-is-of-illegal-length