将字节数组转换为BigInteger

3

我的数字是从左到右以字节数组形式表示的256进制数。我想将它们转换为BigInteger,使得以下示例可以正常工作:

  • [5] -> 5
  • [200] -> 200
  • [0,1] -> 256
  • [100,2] -> 612

我想出了以下解决方案:

    byte[] input = new byte[]{(byte) 200,2};
    BigInteger a = BigInteger.ZERO;
    BigInteger base = BigInteger.valueOf(256);
    for (int i = 0; i < input.length; i++) {
        a = a.add(BigInteger.valueOf(input[i] & 0xFF).multiply(base.pow(i)));
    }
    System.out.println(a);

虽然这个方法能用,但感觉很低效。有没有更高效的方法?

如果这段代码能够正常运行,那么这个问题就不适合在 Stack Overflow 上讨论,但是可以考虑在我们的姊妹站点 Code Review 上进行讨论。 - Joe C
@JoeC 我想找到一种更高效的方法来完成这个任务。创建多个BigIntegers并不是你能做的最好的选择.... - Ilya Gazman
@ThomasFritsch 我得到了不同的字节顺序,我的示例无法以那种方式进行转换。 - Ilya Gazman
@Ilya_Gazman 你可以反转数组中的字节顺序,然后 使用 new BigInteger(array)。这比你目前做的要更有效率。 - Andreas
@Andreas,听起来比我的解决方案更有效,但它对我没有起作用。你能用那个想法让我的例子工作吗? - Ilya Gazman
2个回答

9
创建一个BigInteger对象的最简单方法是使用new BigInteger​(byte[] val)构造函数,该函数可以从字节数组中创建出一个BigInteger对象。
引用如下:

将包含BigInteger的二进制的二补数转换为BigInteger。输入数组被假定为大端字节序:最重要的字节在第一个元素中。

由于您的输入数组采用小端字节顺序,并且您不希望返回负数,因此您需要反转字节并确保第一个字节为0-127,以便不设置符号位。最简单的方法是将第一个字节设为0
例如:[2, 20, 200] -> [0, 200, 20, 2] 以下是相应代码:
private static BigInteger toBigInt(byte[] arr) {
    byte[] rev = new byte[arr.length + 1];
    for (int i = 0, j = arr.length; j > 0; i++, j--)
        rev[j] = arr[i];
    return new BigInteger(rev);
}

测试

byte[][] data = { {5},
                  {(byte)200},
                  {0,1},
                  {100,2} };
for (byte[] arr : data)
    System.out.println(toBigInt(arr));

输出

5
200
256
612

2

我知道你能做到这一点:

import java.math.BigInteger;
import java.util.BitSet;

public class Main {
    public static void main(String[] argv) throws Exception {
        // A negative value
        byte[] bytes = new byte[] { (byte) 0xFF, 0x00, 0x00 }; // -65536
        // A positive value
        bytes = new byte[] { 0x1, 0x00, 0x00 }; // 65536
        BitSet set = BitSet.valueOf(bytes);
        set.flip(0, set.length());
        byte[] flipped = set.toByteArray();

        BigInteger bi = new BigInteger(flipped);
    }
}

我使用BitSet来交换位,因为你希望从左到右,但BigInteger构造函数使用从右到左。


2
字节顺序与问题中的相反。 - Andreas
抱歉,我没看到,我已经修复了。 - Albanninou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接