2014-05-07 13 views
5

Prosty scenariusz: Masz tablicę bajtówDlaczego metoda java Integer.toBinaryString (-128) generuje siedem cyfr?

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

go wydrukować w formacie binarnym można użyć kodu:

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

(got that kod z this stack overflow thread)

Uzyskać to wyjście:

00000001 
00000010 
00000011 



Ale jeśli oznaczyć -128 na końcu ...

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

00000001 
00000010 
00000011 
0000000 

WOAH! Siedmiocyfrowy numer binarny? Wyczuwam, że ma to coś wspólnego z dopełnieniem dwójki, ale im więcej próbuję czytać, tym bardziej się mylę. Spodziewałem 10000000 pojawić się w czwartym wierszu zamiast ...

Może ktoś wyjaśnić, dlaczego Integer.toBinaryString z -128 jest siedem cyfr w stosunkowo prosty sposób?


Ye olde javadoc mówi 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. Ale jak powiedziałem ... mnie po prostu myli.



Kontekst całej tej sprawie jest to, że staram się kodowania niektórych funkcji SHA w Javie. Nie pytaj mnie dlaczego, nie wiem nawet ... jestem po prostu ciekawa/sama się podjudzam/denerwuję się :)

Wypełnienie wiadomości do użycia w funkcji SHA-256 (co czyni ją wielokrotnością 512 długości bitów) zgodnie the documentation jest połączeniem:

  1. pierwotny komunikat
  2. pojedyncza 1 nieco
  3. 0 bitów do ostatnich 64 bitów
  4. długości pierwotnej wiadomości jako 64-bitowa wartość

Ponieważ moje wiadomości najprawdopodobniej będzie w kodach ASCII 8-bitowych, po prostu trzeba oznaczyć w 10000000 dla # 2 ... wtedy mogę po prostu policzyć 0 bajtów dodać, że powinnam Trzeba zaplanować komunikaty, które nie są wielokrotnościami 8. Problem polega na tym, że 10000000.

Odpowiedz

6
(-128 + 0x100) = 
(256 - 128) = 128 = 
0b10000000 

Integer.toBinaryString(0b10000000) = "10000000" 

"10000000".substring(1) = "0000000" 
+0

Dlatego nie powinienem zezwalać na kodowanie w nocy. Przepraszam za czas marnowania haha ​​ – snickers10m

1

Wystąpił błąd w wątku przepełnienia stosu, z którego skopiowano. 0x100 ma 256 znaków dziesiętnych, więc ...

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

Innymi słowy, ponieważ 128 jest mniejsze niż Byte.MAX_VALUE, efekt paddingu nie jest zamierzony. Możesz wybrać większą wartość padu - spróbuj 0x200 i usuń pierwsze dwa znaki ??

FWIW, jest zrozumiałe, że tego typu błędy b/c wartości ujemnego bajtu są trochę dziwne rzeczy java. No cóż.

+0

Tak więc w kontekście tego, co próbowałem osiągnąć ... Czy bajt w tablicy wynosi 10000000, nawet jeśli sposób, w jaki ją wyświetlam, nie był? Czy jest jakiś inny sposób, w jaki powinienem wstawić 1, jako wymaganą funkcję SHA? – snickers10m

+0

W rzeczywistości nie będę wyświetlał pliku binarnego ... Właśnie robiłem to, aby sprawdzić, czy działa ... Potrzebuję tylko tablicy bajtów z komunikatem, a następnie 10000000, które będą działały w operacjach bitowych. – snickers10m