Cómo convertir un byte a su representación de cadena binaria

92

Por ejemplo, los bits en un byte Bson 10000010, cómo puedo asignar los bits a la cadena strliteral, es decir, str = "10000010".

Editar

Leí el byte de un archivo binario y lo almacené en la matriz de bytes B. Yo uso System.out.println(Integer.toBinaryString(B[i])). el problema es

(a) cuando los bits comienzan con (más a la izquierda) 1, la salida no es correcta porque se convierte B[i]en un valor int negativo.

(b) si los bits comienzan con 0, la salida ignora 0, por ejemplo, suponga que B[0]tiene 00000001, la salida es en 1lugar de00000001

Sean
fuente
2
Estoy confundido; es esto un truco?
Dave Newton
1
¿Está preguntando cómo convertir bytea en una cadena en base 2?
SLaks
Acabo de añadir una respuesta a otro hilo para hacer esto (la conversión de un valor en una cadena de dígitos binarios), que trabaja para Boolean, Byte, Short, Char, Int, y Long. stackoverflow.com/a/54950845/501113
chaotic3quilibrium
String # Format () podría manejar esto, si le dijiste que usara un ancho de 8. Igualmente System.out.printf ().
NomadMaker

Respuestas:

170

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

João Silva
fuente
Probé este método. En mi caso, leí el byte de un archivo binario y lo almacené en la matriz de bytes B. Yo uso System.out.println(Integer.toBinaryString(B[i])). Cuando utilizo estos métodos, el problema es (a) cuando los bits comienzan con (más a la izquierda) 1, la salida no es correcta porque se convierte B[i]en un valor int negativo. (b) si los bits comienzan con 0, la salida se ignora 0, por ejemplo, suponga que B[0]tiene 00000001, la salida es en 1lugar de00000001
Sean
1
@Sean: a) sucede porque a byteen Java es un entero de complemento a dos con signo de 8 bits. Su valor mínimo es -128 (2 ^ 8) y su valor máximo es 127; b) Puede solucionarlo fácilmente usando esto String.format("%8s", Integer.toBinaryString(b)).replace(' ', '0')para rellenar la cadena resultante con ceros a la izquierda.
João Silva
1
@ João: gracias por tu consejo. ¿Tiene alguna idea sobre cómo abordar (a), cómo almacenar el formato de bits original (comienza con 1) en la cadena?
Sean
1
@Sean: Sí, solo &con 0xFF.
João Silva
12
@Sean: & 0xFFbásicamente convierte signed bytea en un unsigned integer. Por ejemplo, -129como dijiste, está representado por 11111111111111111111111110000001. En este caso, básicamente desea los primeros 8 bits (menos significativos), por lo que Y ( &) con 0xFF( 00000000000000000000000011111111), limpiando efectivamente los 1 a la izquierda que no nos importan, dejando solo 10000001.
João Silva
34

Usé esto. Idea similar a otras respuestas, pero no vi el enfoque exacto en ninguna parte :)

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

0xFFes 255, o 11111111(valor máximo para un byte sin signo). 0x100es 256, o100000000

La &conversión del byte a un número entero. En ese punto, puede ser cualquier cosa desde 0- 255( 00000000hasta 11111111, excluí los 24 bits iniciales). + 0x100y .substring(1)asegúrese de que haya ceros a la izquierda.

Lo cronometré en comparación con la respuesta de João Silva , y esto es 10 veces más rápido. http://ideone.com/22DDK1 No incluí la respuesta de Pshemo porque no se rellena correctamente.

Raekye
fuente
¡Oye! tengo una pregunta sobre esto. Tengo una cadena de representación Base64 de un PDF, necesito convertir a Binary. Básicamente, Base64-> byte-> binary ¿Funcionará este código?
Sid
¿Qué hace exactamente el + 0x100? Estás agregando 256 al entero resultante, pero ¿por qué?
Conner Dassen
1
@ConnerDassen Asegura que la cadena binaria se rellene con 0. Por ejemplo, si bes 1, sin + 0x100usted solo obtendrá "1"como su cadena. Al agregar 1, obtienes 100000001, y si tomas la subcadena ignorando el primer carácter, obtendrás el correcto "00000001". Si no desea que su cuerda esté acolchada, simplemente puede usar Integer.toBinaryString(b & 0xff). Las & 0xffcorrecciones de los / de dos cuestiones negativas del complemento
Raekye
8

¿Es esto lo que estás buscando?

convertir de String a byte

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

convertir de byte a String

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

O como dijo João Silva en su comentario para agregar interlineado 0, podemos formatear la cadena a la longitud 8 y reemplazar los espacios iniciales resultantes con cero, por lo que en el caso de una cadena como " 1010"obtendremos"00001010"

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

Puede verificar cada bit en el byte y luego agregar 0 o 1 a una cadena. Aquí hay un pequeño método de ayuda que escribí para probar:

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

Obtenga cada bit de byte y conviértalo en cadena. Digamos que el byte tiene 8 bits y podemos obtenerlos uno por uno mediante el movimiento de bits. Por ejemplo, movemos el segundo bit del byte 6 bits a la derecha, el segundo bit al final del bit de 8 bits, luego y (&) con 0x0001 para limpiar los bits frontales.

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();
}
jamee
fuente
¿Podría editar su respuesta para dar una explicación de por qué este código responde a la pregunta? Se desaconsejan las respuestas de solo código , porque no enseñan la solución.
DavidPostill
2

Este código demostrará cómo se puede dividir un int de Java en sus 4 bytes consecutivos. Luego podemos inspeccionar cada byte usando métodos Java en comparación con la interrogación de byte / bit de bajo nivel.

Este es el resultado esperado cuando ejecuta el siguiente código:

[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

Aquí está el código para ejecutar:

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

}
Naresh Maharaj
fuente
2
Integer.toBinaryString((byteValue & 0xFF) + 256).substring(1)
Timofey Gorshkov
fuente
2

Lo siento, sé que esto es un poco tarde ... Pero tengo una manera mucho más fácil ... Para cadena binaria:

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

método 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;
}
Jp Plata
fuente
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();
}
Shahidul
fuente
1

Puede trabajar con BigInteger como el siguiente ejemplo, especialmente si tiene 256 bits o más:

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

Otro ejemplo que acepta bytes:

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

Resultado:

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

binary: 101010001101000011001010010000001100111011010010111001001101100001000000110111101101110001000000111010001101000011001010010000001110010011001010110010000100000011001000111001001100101011100110111001100101110
hex: 546865206769726c206f6e20746865207265642064726573732e

También puede trabajar para convertir formato binario a byte

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

Nota: Para el formato de cadena para su formato binario, puede usar la siguiente muestra

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

Una respuesta simple podría ser:

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
Daniel De León
fuente
0

Todos sabemos que Java no proporciona nada parecido a la palabra clave unsigned. Además, una byteprimitiva de acuerdo con la especificación de Java representa un valor entre −128y 127. Por ejemplo, si a bytees castpara un intJava interpretará el primero bitcomo elsign y usará la extensión del signo.

Entonces, ¿cómo convertir un byte mayor que 127 en su representación de cadena binaria?

Nada le impide ver a bytesimplemente como 8 bits e interpretar esos bits como un valor entre 0y 255. Además, debe tener en cuenta que no hay nada que pueda hacer para forzar su interpretación sobre el método de otra persona. Si un método acepta un byte, entonces ese método acepta un valor entre −128y127 menos que se indique explícitamente lo contrario.

Entonces, la mejor manera de resolver esto es convertir el bytevalor en un intvalor llamando al Byte.toUnsignedInt()método o convirtiéndolo en un intprimitivo (int) signedByte & 0xFF. Aquí tienes un ejemplo:

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

Salida

8-bit header:
10000000
11100010
01100000
11101010
Teocci
fuente
-1

Solo adivino aquí, pero si tiene un Byte, ¿no podría simplemente invocar toString () en el objeto para obtener el valor? ¿O, mirando la API , usando byteValue ()?

geogaddi
fuente