Java (BigInteger из массива байт)


Я использую следующий код для создания 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

Что я делаю не так?

2 5

2 ответа:

Вы передаете в массив байтов, где первый байт имеет верхний бит, который задан, что делает его отрицательным. Из документации конструктора :

Преобразует массив байтов, содержащий двоичное представление BigInteger с двумя дополнениями, в BigInteger. Предполагается, что входной массив находится в байтовом порядке большого конца: наиболее значимый байт находится в нулевом элементе.

Двоичное представление с двумя дополнениями с ведущим битом набора является отрицательный.

Чтобы получить желаемый результат, вы можете выполнить любое из следующих действий:

  • префикс шестнадцатеричной строки с "00", так что вы всегда будете получать верхний байт 0
  • передайте шестнадцатеричную строку прямо в конструктор BigInteger(String, int), где знак выводится из наличия или отсутствия "-" в начале строки. (Очевидно, что вы бы прошли в 16 в качестве базы.)
  • используйте конструктор BigInteger(int, byte[]), передавая 1 в качестве значения signum

Если ваш реальный контекст таков, что у вас уже есть массив байтов, и вы только разбирали его из шестнадцатеричной строки для целей тестирования, я бы использовал третий вариант. Если у вас действительно есть шестнадцатеричная строка в качестве входных данных, я бы использовал второй вариант.

Попробуйте

BigInteger bigInt = new BigInteger(HexString, 16);