BigInteger to byte[]

2022-09-02 19:48:31

我需要将Java BigInteger实例转换为其以字节为单位的值。从API中,我得到了这个方法,它返回一个byte[],其中包含这个BigInteger的二进制补码表示。toByteArray()

由于我所有的数字都是正128位(16字节)整数,我不需要2的补码形式,它给我128位+符号位(129位)...

有没有办法直接从BigInteger获得标准(没有2的补码形式)表示?

如果没有,我怎样才能右移整个byte[17]数组以丢失符号位以获得byte[16]数组?


答案 1

你根本不需要改变。符号位是字节数组中最重要的(= 最左边)位。由于您知道您的数字将始终为正数,因此可以保证为 0。但是,数组作为一个整体是右对齐的。

因此,有两种情况:最左边的字节是否0x00。如果0x00您可以安全地将其放下:

byte[] array = bigInteger.toByteArray();
if (array[0] == 0) {
    byte[] tmp = new byte[array.length - 1];
    System.arraycopy(array, 1, tmp, 0, tmp.length);
    array = tmp;
}

如果它不是0,那么你不能删除它 - 但是你的数组已经在你想要的表示中,所以你不必做任何事情。

上述代码应该适用于这两种情况。


答案 2

字节数组中的第一个(最高有效)字节可能不仅包含符号位,还包含普通位。

例如,这个BigInteger:

new BigInteger("512")
    .add(new BigInteger("16"))
    .add(new BigInteger("1"));

具有以下位模式:00000010 00010001

也就是说,顶部字节(带有符号位)也具有您期望的“正常”位。

那么,您想找回什么呢?

00000010 00010001 (what you have) or
00000100 0010001? or
10000100 01??????