Na przykład bity w bajcie B
to 10000010
, jak mogę przypisać bity do ciągu str
dosłownie, to znaczy str = "10000010"
.
Edytować
Czytam bajt z pliku binarnego i zapisuję go w tablicy bajtów B
. Używam System.out.println(Integer.toBinaryString(B[i]))
. problemem jest
(a) gdy bity zaczynają się od (skrajnie lewy) 1, dane wyjściowe są nieprawidłowe, ponieważ są konwertowane B[i]
na ujemną wartość int.
(b) jeśli bity zaczynają się od 0
, wyjście ignoruje 0
, na przykład, załóżmy, że B[0]
ma 00000001, wyjście jest 1
zamiast00000001
byte
ciąg znaków w bazie 2?Boolean
,Byte
,Short
,Char
,Int
, iLong
. stackoverflow.com/a/54950845/501113Odpowiedzi:
Zastosowanie
Integer#toBinaryString()
:byte b1 = (byte) 129; String s1 = String.format("%8s", Integer.toBinaryString(b1 & 0xFF)).replace(' ', '0'); System.out.println(s1); // 10000001 byte b2 = (byte) 2; String s2 = String.format("%8s", Integer.toBinaryString(b2 & 0xFF)).replace(' ', '0'); System.out.println(s2); // 00000010
DEMO .
źródło
B
. UżywamSystem.out.println(Integer.toBinaryString(B[i]))
. Kiedy używam tej metody, problem polega na tym, że (a) gdy bity zaczynają się od (skrajnie lewy) 1, dane wyjściowe są nieprawidłowe, ponieważ są konwertowaneB[i]
na ujemną wartość int. (b) jeśli bity zaczynają się od 0, wyjście ignoruje0
, na przykład, załóżmy, żeB[0]
ma00000001
, wyjście jest1
zamiast00000001
byte
w Javie jest 8-bitową liczbą całkowitą uzupełnienia do dwóch ze znakiem . Jego minimalna wartość to -128 (2 ^ 8), a maksymalna to127
; b) Możesz to łatwo naprawić, używając tegoString.format("%8s", Integer.toBinaryString(b)).replace(' ', '0')
do wypełnienia otrzymanego ciągu zerami w lewo.&
to z0xFF
.& 0xFF
zasadzie konwertuje asigned byte
naunsigned integer
. Na przykład,-129
jak powiedziałeś, jest reprezentowany przez11111111111111111111111110000001
. W tym przypadku w zasadzie potrzebujesz pierwszych (najmniej znaczących) 8 bitów, więc ORAZ (&
) to za pomocą0xFF
(00000000000000000000000011111111
), skutecznie czyszcząc jedynki po lewej stronie, na których nam nie zależy, pomijając tylko10000001
.Użyłem tego. Podobny pomysł do innych odpowiedzi, ale nigdzie nie widziałem dokładnego podejścia :)
System.out.println(Integer.toBinaryString((b & 0xFF) + 0x100).substring(1));
0xFF
wynosi 255 lub11111111
(maksymalna wartość dla bajtu bez znaku).0x100
to 256 lub100000000
&
Upcasts bajtu do całkowitej. W tym momencie może to być wszystko od0
-255
(00000000
do11111111
, wykluczyłem początkowe 24 bity).+ 0x100
i.substring(1)
upewnij się, że na początku będą zera.Zmierzyłem czas w porównaniu z odpowiedzią João Silvy , a to ponad 10 razy szybciej. http://ideone.com/22DDK1 Nie zamieściłem odpowiedzi Pshemo, ponieważ nie jest ona poprawnie wypełniona.
źródło
b
tak1
, bez+ 0x100
ciebie po prostu otrzymasz"1"
jako swój ciąg. Dodając1
, otrzymujesz100000001
, a jeśli weźmiesz podciąg, ignorując pierwszy znak, otrzymasz właściwy"00000001"
. Jeśli nie chcesz, aby Twój sznurek był wyściełany, możesz po prostu użyćInteger.toBinaryString(b & 0xff)
. Te& 0xff
poprawki negatywne / two za kwestie dopełniaczaCzy tego szukasz?
konwertowanie z String na bajt
byte b = (byte)(int)Integer.valueOf("10000010", 2); System.out.println(b);// output -> -126
konwertowanie z bajtu na ciąg
System.out.println(Integer.toBinaryString((b+256)%256));// output -> "10000010"
Lub, jak powiedział João Silva w swoim komentarzu, aby dodać początek
0
, możemy sformatować ciąg do długości 8 i zamienić wynikowe spacje wiodące na zero, więc w przypadku łańcucha takiego jak" 1010"
otrzymamy"00001010"
System.out.println(String.format("%8s", Integer.toBinaryString((b + 256) % 256)) .replace(' ', '0'));
źródło
Możesz sprawdzić każdy bit w bajcie, a następnie dołączyć 0 lub 1 do ciągu. Oto mała pomocnicza metoda, którą napisałem do testowania:
public static String byteToString(byte b) { byte[] masks = { -128, 64, 32, 16, 8, 4, 2, 1 }; StringBuilder builder = new StringBuilder(); for (byte m : masks) { if ((b & m) == m) { builder.append('1'); } else { builder.append('0'); } } return builder.toString(); }
źródło
Pobierz każdy bit bajtu i przekonwertuj go na łańcuch. Powiedzmy, że bajt ma 8 bitów i możemy je uzyskać jeden po drugim za pomocą ruchu bitowego. Na przykład, przesuwamy drugi bit z bajtu 6 bitów w prawo, drugi bit na końcu z 8 bitów, a następnie (&) za pomocą 0x0001, aby wyczyścić bity przednie.
public static String getByteBinaryString(byte b) { StringBuilder sb = new StringBuilder(); for (int i = 7; i >= 0; --i) { sb.append(b >>> i & 1); } return sb.toString(); }
źródło
Ten kod pokaże, jak java int można podzielić na 4 kolejne bajty. Następnie możemy sprawdzić każdy bajt za pomocą metod Java w porównaniu z zapytaniem bajt / bit niskiego poziomu.
To jest oczekiwany wynik po uruchomieniu poniższego kodu:
[Input] Integer value: 8549658 Integer.toBinaryString: 100000100111010100011010 Integer.toHexString: 82751a Integer.bitCount: 10 Byte 4th Hex Str: 0 Byte 3rd Hex Str: 820000 Byte 2nd Hex Str: 7500 Byte 1st Hex Str: 1a (1st + 2nd + 3rd + 4th (int(s)) as Integer.toHexString: 82751a (1st + 2nd + 3rd + 4th (int(s)) == Integer.toHexString): true Individual bits for each byte in a 4 byte int: 00000000 10000010 01110101 00011010
Oto kod do uruchomienia:
public class BitsSetCount { public static void main(String[] args) { int send = 8549658; System.out.println( "[Input] Integer value: " + send + "\n" ); BitsSetCount.countBits( send ); } private static void countBits(int i) { System.out.println( "Integer.toBinaryString: " + Integer.toBinaryString(i) ); System.out.println( "Integer.toHexString: " + Integer.toHexString(i) ); System.out.println( "Integer.bitCount: "+ Integer.bitCount(i) ); int d = i & 0xff000000; int c = i & 0xff0000; int b = i & 0xff00; int a = i & 0xff; System.out.println( "\nByte 4th Hex Str: " + Integer.toHexString(d) ); System.out.println( "Byte 3rd Hex Str: " + Integer.toHexString(c) ); System.out.println( "Byte 2nd Hex Str: " + Integer.toHexString(b) ); System.out.println( "Byte 1st Hex Str: " + Integer.toHexString(a) ); int all = a+b+c+d; System.out.println( "\n(1st + 2nd + 3rd + 4th (int(s)) as Integer.toHexString: " + Integer.toHexString(all) ); System.out.println("(1st + 2nd + 3rd + 4th (int(s)) == Integer.toHexString): " + Integer.toHexString(all).equals(Integer.toHexString(i) ) ); System.out.println( "\nIndividual bits for each byte in a 4 byte int:"); /* * Because we are sending the MSF bytes to a method * which will work on a single byte and print some * bits we are generalising the MSF bytes * by making them all the same in terms of their position * purely for the purpose of printing or analysis */ System.out.print( getBits( (byte) (d >> 24) ) + " " + getBits( (byte) (c >> 16) ) + " " + getBits( (byte) (b >> 8) ) + " " + getBits( (byte) (a >> 0) ) ); } private static String getBits( byte inByte ) { // Go through each bit with a mask StringBuilder builder = new StringBuilder(); for ( int j = 0; j < 8; j++ ) { // Shift each bit by 1 starting at zero shift byte tmp = (byte) ( inByte >> j ); // Check byte with mask 00000001 for LSB int expect1 = tmp & 0x01; builder.append(expect1); } return ( builder.reverse().toString() ); } }
źródło
Integer.toBinaryString((byteValue & 0xFF) + 256).substring(1)
źródło
Przepraszam, wiem, że to trochę za późno ... Ale mam o wiele łatwiejszy sposób ... Do łańcucha binarnego:
//Add 128 to get a value from 0 - 255 String bs = Integer.toBinaryString(data[i]+128); bs = getCorrectBits(bs, 8);
metoda getCorrectBits:
private static String getCorrectBits(String bitStr, int max){ //Create a temp string to add all the zeros StringBuilder sb = new StringBuilder(); for(int i = 0; i < (max - bitStr.length()); i ++){ sb.append("0"); } return sb.toString()+ bitStr; }
źródło
String byteToBinaryString(byte b){ StringBuilder binaryStringBuilder = new StringBuilder(); for(int i = 0; i < 8; i++) binaryStringBuilder.append(((0x80 >>> i) & b) == 0? '0':'1'); return binaryStringBuilder.toString(); }
źródło
Możesz pracować z BigInteger, jak na poniższym przykładzie, szczególnie jeśli masz 256 bitów lub więcej:
String string = "10000010"; BigInteger biStr = new BigInteger(string, 2); System.out.println("binary: " + biStr.toString(2)); System.out.println("hex: " + biStr.toString(16)); System.out.println("dec: " + biStr.toString(10));
Inny przykład, który akceptuje bajty:
String string = "The girl on the red dress."; byte[] byteString = string.getBytes(Charset.forName("UTF-8")); System.out.println("[Input String]: " + string); System.out.println("[Encoded String UTF-8]: " + byteString); BigInteger biStr = new BigInteger(byteString); System.out.println("binary: " + biStr.toString(2)); // binary System.out.println("hex: " + biStr.toString(16)); // hex or base 16 System.out.println("dec: " + biStr.toString(10)); // this is base 10
Wynik:
[Input String]: The girl on the red dress. [Encoded String UTF-8]: [B@70dea4e binary: 101010001101000011001010010000001100111011010010111001001101100001000000110111101101110001000000111010001101000011001010010000001110010011001010110010000100000011001000111001001100101011100110111001100101110 hex: 546865206769726c206f6e20746865207265642064726573732e
Możesz także pracować nad konwersją formatu binarnego do formatu bajtowego
try { System.out.println("binary to byte: " + biStr.toString(2).getBytes("UTF-8")); } catch (UnsupportedEncodingException e) {e.printStackTrace();}
Uwaga: do formatowania ciągów znaków w formacie binarnym można użyć poniższego przykładu
String.format("%256s", biStr.toString(2).replace(' ', '0')); // this is for the 256 bit formatting
źródło
Prosta odpowiedź może brzmieć:
System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})); // 0 System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1})); // 1 System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0})); // 256 System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0})); // 65536 System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0})); // 16777216 System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0})); // 4294967296 System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0})); // 1099511627776 System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0})); // 281474976710656 System.out.println(new BigInteger(new byte[]{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0})); // 72057594037927936 System.out.println(new BigInteger(new byte[]{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0})); // 18446744073709551616 System.out.println(new BigInteger(new byte[]{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0})); // 4722366482869645213696 System.out.println(new BigInteger(new byte[]{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})); // 1208925819614629174706176 System.out.println(Long.MAX_VALUE); // 9223372036854775807
źródło
Wszyscy wiemy, że Java nie zapewnia niczego podobnego do słowa kluczowego unsigned. Ponadto
byte
prymityw zgodnie ze specyfikacją Javy reprezentuje wartość między−128
a127
. Na przykład, jeśli abyte
jestcast
dlaint
języka Java, zinterpretuje pierwszebit
jako rozszerzeniesign
i użyje rozszerzenia znaku.Jak więc przekonwertować bajt większy niż
127
na jego reprezentację w postaci łańcucha binarnego?Nic nie stoi na przeszkodzie, aby
byte
traktować po prostu jako 8-bitów i interpretować te bity jako wartość między0
a255
. Pamiętaj też, że nie możesz nic zrobić, aby narzucić swoją interpretację metodom innej osoby. Jeśli metoda akceptuje abyte
, wówczas ta metoda przyjmuje wartość między−128
a127
chyba że wyraźnie określono inaczej.Dlatego najlepszym sposobem rozwiązania tego problemu jest przekonwertowanie
byte
wartości naint
wartość przez wywołanieByte.toUnsignedInt()
metody lub rzutowanie jej jakoint
prymitywu(int) signedByte & 0xFF
. Tutaj masz przykład:public class BinaryOperations { public static void main(String[] args) { byte forbiddenZeroBit = (byte) 0x80; buffer[0] = (byte) (forbiddenZeroBit & 0xFF); buffer[1] = (byte) ((forbiddenZeroBit | (49 << 1)) & 0xFF); buffer[2] = (byte) 96; buffer[3] = (byte) 234; System.out.println("8-bit header:"); printBynary(buffer); } public static void printBuffer(byte[] buffer) { for (byte num : buffer) { printBynary(num); } } public static void printBynary(byte num) { int aux = Byte.toUnsignedInt(num); // int aux = (int) num & 0xFF; String binary = String.format("%8s', Integer.toBinaryString(aux)).replace(' ', '0'); System.out.println(binary); } }
Wynik
źródło
Kolejna wskazówka dla tych, którzy muszą masowo konwertować bajty na ciągi binarne: używaj tabeli przeglądowej zamiast używać tych operacji na ciągach znaków przez cały czas. Jest to o wiele szybsze niż ciągłe wywoływanie funkcji konwersji
public class ByteConverterUtil { private static final String[] LOOKUP_TABLE = IntStream.range(0, Byte.MAX_VALUE - Byte.MIN_VALUE + 1) .mapToObj(intValue -> Integer.toBinaryString(intValue + 0x100).substring(1)) .toArray(String[]::new); public static String convertByte(final byte byteValue) { return LOOKUP_TABLE[Byte.toUnsignedInt(byteValue)]; } public static void main(String[] args){ System.out.println(convertByte((byte)0)); //00000000 System.out.println(convertByte((byte)2)); //00000010 System.out.println(convertByte((byte)129)); //10000001 System.out.println(convertByte((byte)255)); //11111111 } }
źródło
Zgaduję, ale jeśli masz Byte, czy nie możesz po prostu wywołać metody toString () na obiekcie, aby uzyskać wartość? Albo spoglądając na interfejs API , używając byteValue ()?
źródło