Come convertire un byte nella sua rappresentazione di stringa binaria


92

Ad esempio, i bit in un byte Bsono 10000010, come posso assegnare i bit alla stringa strletteralmente, cioè str = "10000010".

modificare

Ho letto il byte da un file binario e l'ho memorizzato nell'array di byte B. Io uso System.out.println(Integer.toBinaryString(B[i])). il problema è

(a) quando i bit iniziano con (più a sinistra) 1, l'output non è corretto perché viene convertito B[i]in un valore int negativo.

(b) se i bit iniziano con 0, l'uscita ignora 0, ad esempio, supponiamo che B[0]abbia 00000001, l'uscita è 1invece di00000001


2
Non ho capito bene; è un trucco?
Dave Newton,

1
Stai chiedendo come convertire a bytein una stringa in base 2?
SLaks

Ho appena aggiunto una risposta a un altro thread per fare questo (conversione di un valore a una stringa di cifre binarie), che lavora per Boolean, Byte, Short, Char, Int, e Long. stackoverflow.com/a/54950845/501113
chaotic3quilibrium

Stringa # Format () potrebbe essere in grado di gestirlo, se gli dicessi di usare una larghezza di 8. Allo stesso modo System.out.printf ().
NomadMaker

Risposte:


169

Usa 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 .


Ho provato questo metodo. Nel mio caso, ho letto il byte da un file binario e l'ho memorizzato nell'array di byte B. Io uso System.out.println(Integer.toBinaryString(B[i])). Quando utilizzo questi metodi, il problema è (a) quando i bit iniziano con (a sinistra) 1, l'output non è corretto perché viene convertito B[i]in un valore int negativo. (b) se i bit iniziano con 0, l'output ignora 0, ad esempio, si presume B[0]abbia 00000001, l'output è 1invece di00000001
Sean

1
@Sean: a) accade perché a bytein Java è un intero con complemento a due con segno a 8 bit. Il suo valore minimo è -128 (2 ^ 8) e il suo valore massimo è 127; b) Puoi facilmente risolverlo usando questo String.format("%8s", Integer.toBinaryString(b)).replace(' ', '0')per riempire a sinistra la stringa risultante con zeri.
João Silva

1
@ João: grazie per i tuoi consigli. Hai qualche idea su come indirizzare (a), come memorizzare il formato bit originale (inizia con 1) nella stringa?
Sean

1
@ Sean: Sì, basta &con 0xFF.
João Silva

11
@Sean: & 0xFFconverte fondamentalmente a signed bytein un file unsigned integer. Ad esempio, -129come hai detto, è rappresentato da 11111111111111111111111110000001. In questo caso, fondamentalmente vuoi i primi 8 bit (meno significativi), quindi AND ( &) con 0xFF( 00000000000000000000000011111111), pulendo efficacemente gli 1 a sinistra che non ci interessano, tralasciando solo 10000001.
João Silva

32

Ho usato questo. Idea simile ad altre risposte, ma non ho visto l'approccio esatto da nessuna parte :)

System.out.println(Integer.toBinaryString((b & 0xFF) + 0x100).substring(1));

0xFFè 255 o 11111111(valore massimo per un byte senza segno). 0x100è 256, o100000000

Il &upcasts il byte da un numero intero. A quel punto, può essere qualsiasi cosa da 0- 255( 00000000a 11111111, ho escluso i 24 bit iniziali). + 0x100e .substring(1)assicurati che ci siano degli zeri iniziali.

L'ho cronometrato rispetto alla risposta di João Silva , e questo è oltre 10 volte più veloce. http://ideone.com/22DDK1 Non ho incluso la risposta di Pshemo perché non si riempie correttamente.


Hey! ho una domanda su questo. Ho una stringa di rappresentazione Base64 di un PDF, devo convertirlo in binario. Fondamentalmente, Base64-> byte-> binary.Will this code work?
Sid

Cosa fa esattamente il + 0x100? Stai aggiungendo 256 al numero intero risultante, ma perché?
Conner Dassen

1
@ConnerDassen Assicura che la stringa binaria sia 0 riempita. Ad esempio, se bè 1, senza di + 0x100te otterrai solo "1"come stringa. Aggiungendo 1, ottieni 100000001, e se prendi la sottostringa ignorando il primo carattere otterrai il giusto "00000001". Se non vuoi che la tua corda sia imbottita puoi semplicemente usare Integer.toBinaryString(b & 0xff). Le & 0xffcorrezioni i negativi / due di questioni complemento
Raekye

8

E 'questo quello che stai cercando?

conversione da String a byte

byte b = (byte)(int)Integer.valueOf("10000010", 2);
System.out.println(b);// output -> -126

conversione da byte a String

System.out.println(Integer.toBinaryString((b+256)%256));// output -> "10000010"

O come ha detto João Silva nel suo commento per aggiungere l'interlinea 0possiamo formattare la stringa alla lunghezza 8 e sostituire gli spazi iniziali risultanti con zero, quindi in caso di stringa come " 1010"avremo"00001010"

System.out.println(String.format("%8s", Integer.toBinaryString((b + 256) % 256))
                         .replace(' ', '0'));

5

È possibile controllare ogni bit del byte e quindi aggiungere 0 o 1 a una stringa. Ecco un piccolo metodo di supporto che ho scritto per i test:

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();
}

3

Ottieni ogni bit di byte e converti in stringa. Diciamo che byte ha 8 bit e possiamo ottenerli uno per uno tramite spostamento di bit. Ad esempio, spostiamo il secondo bit del byte 6 bit a destra, il secondo bit alla fine bit di 8 bit, quindi e (&) con 0x0001 per pulire i bit anteriori.

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();
}

Potresti modificare la tua risposta per fornire una spiegazione del motivo per cui questo codice risponde alla domanda? Le risposte di solo codice sono scoraggiate , perché non insegnano la soluzione.
DavidPostill

2

Questo codice dimostrerà come un java int può essere suddiviso nei suoi 4 byte consecutivi. Possiamo quindi ispezionare ogni byte utilizzando metodi Java rispetto all'interrogazione byte / bit di basso livello.

Questo è l'output previsto quando esegui il codice seguente:

[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

Ecco il codice da eseguire:

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() );
    }

}


2

Mi dispiace, so che è un po 'tardi ... Ma ho un modo molto più semplice ... Per una stringa binaria:

//Add 128 to get a value from 0 - 255
String bs = Integer.toBinaryString(data[i]+128);
bs = getCorrectBits(bs, 8);

metodo 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;
}

1
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();
}

0

Sappiamo tutti che Java non fornisce nulla di simile alla parola chiave non firmata. Inoltre, una byteprimitiva secondo le specifiche di Java rappresenta un valore compreso tra −128e 127. Ad esempio, se a bytesta casta intJava interpreterà il primo bitcome signe utilizzerà l'estensione del segno.

Quindi, come convertire un byte maggiore della 127sua rappresentazione di stringa binaria ??

Niente ti impedisce di visualizzare bytesemplicemente come 8 bit e interpretare quei bit come un valore compreso tra 0e 255. Inoltre, devi tenere presente che non puoi fare nulla per forzare la tua interpretazione sul metodo di qualcun altro. Se un metodo accetta a byte, allora quel metodo accetta un valore compreso tra −128e a 127meno che non sia specificato diversamente.

Quindi il modo migliore per risolvere questo problema è convertire il bytevalore in un intvalore chiamando il Byte.toUnsignedInt()metodo o eseguendo il cast come intprimitivo (int) signedByte & 0xFF. Ecco un esempio:

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);
    }
}

Produzione

8-bit header:
10000000
11100010
01100000
11101010

0

Puoi lavorare con BigInteger come nell'esempio seguente, soprattutto se hai 256 bit o più:

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));

Un altro esempio che accetta byte:

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

Risultato:

[Input String]: The girl on the red dress.
[Encoded String UTF-8]: [B@70dea4e

binary: 101010001101000011001010010000001100111011010010111001001101100001000000110111101101110001000000111010001101000011001010010000001110010011001010110010000100000011001000111001001100101011100110111001100101110
hex: 546865206769726c206f6e20746865207265642064726573732e

Puoi anche lavorare per convertire il formato binario in byte

try {
   System.out.println("binary to byte: " + biStr.toString(2).getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {e.printStackTrace();}

Nota: per la formattazione delle stringhe per il formato binario puoi utilizzare l'esempio di seguito

String.format("%256s", biStr.toString(2).replace(' ', '0'));  // this is for the 256 bit formatting

0

Una semplice risposta potrebbe essere:

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

-1

Sto solo indovinando qui, ma se hai un byte, non potresti semplicemente invocare toString () sull'oggetto per ottenere il valore? O, guardando l' API , usando byteValue ()?

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.