BigInteger.toByteArray()返回有目的的前导零?

我正在将bigints转换为二进制,radix16和radix64编码,并看到神秘的msb零填充。 这是一个大问题,我可以通过剥离零填充或者做其他事情来解决这个问题吗?

我的测试代码:

String s; System.out.printf( "%s length %d\n", s = "123456789A", (new BigInteger( s, 16 )).toByteArray().length ); System.out.printf( "%s length %d\n", s = "F23456789A", (new BigInteger( s, 16 )).toByteArray().length ); 

产生输出:

  123456789A length 5 F23456789A length 6 

其中较长的arrays在前面具有零填充。 检查BigInteger.toByteArray()后,我看到:

 public byte[] toByteArray() { int byteLen = bitLength()/8 + 1; byte[] byteArray = new byte[byteLen]; 

现在,我可以找到private int bitLength; ,但我无法找到bitLength()的定义,以确定为什么这个类这样做 – 也许连接到符号扩展?

感谢Jon Skeet的回答。 这是我用来转换的一些代码,很可能它可以进行优化。

 import java.math.BigInteger; import java.util.Arrays; public class UnsignedBigInteger { public static byte[] toUnsignedByteArray(BigInteger value) { byte[] signedValue = value.toByteArray(); if(signedValue[0] != 0x00) { throw new IllegalArgumentException("value must be a psoitive BigInteger"); } return Arrays.copyOfRange(signedValue, 1, signedValue.length); } public static BigInteger fromUnsignedByteArray(byte[] value) { byte[] signedValue = new byte[value.length + 1]; System.arraycopy(value, 0, signedValue, 1, value.length); return new BigInteger(signedValue); } } 

是的,这是记录在案的行为 :

字节数组将采用big-endian字节顺序:最重要的字节位于第0个元素中。 该数组将包含表示此BigInteger所需的最小字节数, 包括至少一个符号位 ,即(ceil((this.bitLength() + 1)/8))

bitLength()记录为:

返回此BigInteger的最小二进制补码表示中的位数,不包括符号位。

换句话说,无论符号如何,具有相同幅度的两个值将始终具有相同的位长度。 将BigInteger视为无符号整数和符号位 – 而toByteArray()返回来自两个部分的所有数据,即“无符号整数所需的位数,以及符号的一位”。