我正在将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
其中较长的数组在前面没有填充。检查BigInteger.toByteArray()后,我看到:
public byte[] toByteArray() {
int byteLen = bitLength()/8 + 1;
byte[] byteArray = new byte[byteLen];
现在,我可以找到private int bitLength;
,但是我无法找到bitLength()的定义,以确定这个类的确切原因 - 也许连接到符号扩展?
答案 0 :(得分:11)
是的,这是documented behaviour:
字节数组将采用big-endian字节顺序:最重要的字节位于第0个元素中。该数组将包含表示此BigInteger所需的最小字节数,包括至少一个符号位,即
(ceil((this.bitLength() + 1)/8))
。
返回此
BigInteger
的最小二进制补码表示中的位数,不包括符号位。
换句话说,无论符号如何,具有相同幅度的两个值将始终具有相同的位长度。可以认为BigInteger
是无符号整数和符号位 - toByteArray()
返回两个部分的所有数据,即“无符号整数所需的位数,以及符号”
答案 1 :(得分:-1)
感谢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);
}
}