IPv6 ip(fc00::) addr是非法长度的

时间:2015-01-29 19:22:52

标签: java ipv6

我在将BigInteger转换为InetAddress时看到错误。只有特定的IP“fc00 ::”才会发生这种情况。这是我的测试代码。如果我遗失了什么,请告诉我。

    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 个答案:

答案 0 :(得分:0)

原因是BigInteger在biStart.toByteArray()中添加了一个额外的字节;

它给你17个字节,这太长了,IPv6地址是16个字节。额外字节位于高端,为0。

如果你在代码中执行此操作,那么它可以工作:

 byte bytes[] = biStart.toByteArray();
 if(bytes.length > 16) {
        byte bytes2[] = new byte[16];
        System.arraycopy(bytes,  1,  bytes2,  0,  bytes2.length);
        bytes = bytes2; 
 }

如果您读取BigInteger.bitLength()的javadoc,则表明该大整数的二进制补码表示至少为 bitLength()+ 1位长。 toByteArray()为您提供了两个补码表示。由于你需要所有128位来重复这个地址,并且你正在谈论一个额外的位,你最终会得到17个字节。

为什么还有一个额外的字节?那是因为你的地址是正数。但是最高字节是fc00,其中二进制补码变为负数。因此,高端必须有一个额外的0位,以保持二进制补码中的正数,因此二进制补码表示需要129位或17个字节,而不是128位和16个字节。对于最高位为1的任何地址,或者以8xxx到fxxx开头的任何地址,例如fc00,都会发生这种情况。