Почему java-метод Integer.toBinaryString(-128) выводит семь цифр?

Простой сценарий: у вас есть массив байтов

byte[] message = { 1, 2, 3 };

Чтобы распечатать его в двоичном формате, вы можете использовать код:

for (byte b : message) {
    System.out.println(Integer.toBinaryString(0x100 + b).substring(1));
}

(Получил этот код из этого поток переполнения стека)

И получите этот вывод:

00000001
00000010
00000011



Но если вы пометите -128 в конце...

byte[] message = { 1, 2, 3, -128 };

00000001
00000010
00000011
0000000

ВАУ! Семизначное двоичное число? Я чувствую, что это как-то связано с дополнением до двух, но чем больше я пытаюсь читать об этом, тем больше путаюсь. Я ожидал, что вместо этого в четвертой строке появится 10000000...

Кто-нибудь может объяснить относительно простыми словами, почему Integer.toBinaryString из -128 состоит из семи цифр?


Старый javadoc говорит The unsigned integer value is the argument plus 2^32 if the argument is negative; otherwise it is equal to the argument. This value is converted to a string of ASCII digits in binary (base 2) with no extra leading 0s. Но, как я уже сказал... просто смущает меня.



Контекст всего этого заключается в том, что я пытаюсь кодировать некоторые функции SHA в java. Не спрашивайте меня, почему, я даже не знаю... Мне просто любопытно/пробую себя/разочаровываю себя :)

Заполнение сообщения для использования в функции SHA-256 (что делает его длину кратной 512 битам) в соответствии с документация представляет собой объединение:

  1. Исходное сообщение
  2. Один 1 бит
  3. 0 бит до последних 64 бит
  4. Исходная длина сообщения в виде 64-битного значения

Поскольку мои сообщения, скорее всего, будут в 8-битных кодах ASCII, мне просто нужно пометить 10000000 для # 2... тогда я могу просто подсчитать количество 0 БАЙТОВ для добавления, мне не нужно планировать сообщения, не кратные 8. Проблема заключается в том, что 10000000.


person snickers10m    schedule 07.05.2014    source источник


Ответы (2)


В потоке переполнения стека, из которого вы скопировали, есть ошибка. 0x100 равно 256 в десятичном виде, так что...

0x100 + 1 = 257 = 0b100000001 (9 digits)
0x100 + (-128) = 128 = 0b10000000 (8 digits)

Другими словами, поскольку 128 меньше, чем Byte.MAX_VALUE, вы не получите эффекта заполнения, который предназначался для плаката. Вы можете выбрать большее значение для заполнения -- попробуйте 0x200 и удалите первые два символа??

FWIW, понятно, что эти типы ошибок b/c отрицательные значения байта - это что-то вроде странной вещи Java. Ну что ж.

person Darren Gilroy    schedule 07.05.2014
comment
Итак, в контексте того, что я пытался выполнить... Равен ли байт в массиве 10000000, даже если то, как я его отображал, не соответствует? Есть ли другой способ вставить 1 в качестве требуемой функции SHA? - person snickers10m; 07.05.2014
comment
На самом деле я не буду отображать двоичный файл... Я просто делал это, чтобы проверить, работает ли он... Мне просто нужен массив байтов с сообщением, за которым следует 10000000, который будет работать в побитовых операциях. - person snickers10m; 07.05.2014

person    schedule
comment
Вот почему мне нельзя разрешать программировать ночью. Извините за потраченное время хаха - person snickers10m; 07.05.2014