Java(来自字节数组的 BigInteger)

Java (BigInteger from byte array)

我正在使用以下代码从十六进制字符串创建 BigInteger 并打印到输出。

package javaapplication2;

import java.math.BigInteger;
import javax.xml.bind.DatatypeConverter;

public class JavaApplication2 {
    public static void main(String[] args) {
        // Number in hexadecimal form
        String HexString = "e04fd020ea3a6910a2d808002b30309d";
        // Convertation from string to byte array
        byte[] ByteArray = toByteArray(HexString);
        // Creation of BigInteger from byte array
        BigInteger BigNumber = new BigInteger(ByteArray);
        // Print result
        System.out.print(BigNumber + "\n");
    }
    public static String toHexString(byte[] array) {
        return DatatypeConverter.printHexBinary(array);
    }

    public static byte[] toByteArray(String s) {
        return DatatypeConverter.parseHexBinary(s);
    }
}

执行此代码后,我得到以下结果:

-42120883064304190395265794005525319523

但我希望看到这样的结果:

298161483856634273068108813426242891933

我做错了什么?

尝试

BigInteger bigInt = new BigInteger(HexString, 16);

您正在传递一个字节数组,其中第一个字节设置了最高位 - 使其为负数。来自 constructor documentation:

Translates a byte array containing the two's-complement binary representation of a BigInteger into a BigInteger. The input array is assumed to be in big-endian byte-order: the most significant byte is in the zeroth element.

前导设置位的二进制补码表示为负数。

要获得您想要的结果,您可以执行以下任一操作:

  • "00" 作为十六进制字符串的前缀,这样您将始终获得 0
  • 的最高字节
  • 将十六进制字符串直接传递给 BigInteger(String, int) 构造函数,其中符号是根据字符串开头是否存在 "-" 推断出来的。 (很明显,您会传入 16 作为基数。)
  • 使用 BigInteger(int, byte[]) 构造函数,传递 1 作为 signum

如果您的 真实 上下文是您已经获得了字节数组,并且您只是出于测试目的从十六进制字符串解析它,我会使用第三个选项。如果你真的有一个十六进制字符串作为输入,我会使用第二个选项。