Подтвердить что ты не робот

BigInteger to byte []

Мне нужно преобразовать экземпляр Java BigInteger в его значение в байтах. Из API я получаю этот метод toByteArray(), который возвращает байт [], содержащий представление двух дополнений этого BigInteger.

Так как все мои числа положительные 128 бит (16 байтов) integer, мне не нужна форма 2's-complement, которая дает мне 128 бит + бит знака (129 бит)...

Есть ли способ получить стандартное представление (без формы 2'-дополнения) непосредственно из BigInteger?

Если нет, как я могу смещать весь массив байтов [17], чтобы потерять бит знака, чтобы получить массив байтов [16]?

4b9b3361

Ответ 1

Вам вообще не нужно менять. Битовый знак является наиболее значимым (= leftmost) бит вашего массива байтов. Поскольку вы знаете, что ваши номера всегда будут положительными, гарантированно будет 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??????

Ответ 3

Вы можете скопировать первый байт. Или вы можете просто игнорировать его.

BigInteger bi = BigInteger.ONE.shiftLeft(127);
byte[] bytes1 = bi.toByteArray();
System.out.println(Arrays.toString(bytes1));
byte[] bytes = new byte[bytes1.length-1];
System.arraycopy(bytes1, 1, bytes, 0, bytes.length);
System.out.println(Arrays.toString(bytes));