Como converter um byte em sua representação de string binária


92

Por exemplo, os bits em um byte Bsão 10000010, como posso atribuir os bits à string strliteralmente, ou seja str = "10000010",.

Editar

Eu li o byte de um arquivo binário e o armazenei na matriz de bytes B. Eu uso System.out.println(Integer.toBinaryString(B[i])). O problema é

(a) quando os bits começam com (mais à esquerda) 1, a saída não é correta porque converte B[i]para um valor int negativo.

(b) se os bits começam com 0, a saída ignora 0, por exemplo, assume que B[0]tem 00000001, a saída é em 1vez de00000001


2
Estou confuso; isso é um truque?
Dave Newton

1
Você está perguntando como converter um byteem uma string na base 2?
SLaks

Acabei de adicionar uma resposta a outro segmento para fazer isso (conversão de um valor a uma seqüência de dígitos binários), que trabalha para Boolean, Byte, Short, Char, Int, e Long. stackoverflow.com/a/54950845/501113
chaotic3quilibrium

String # Format () pode ser capaz de lidar com isso, se você disser para usar uma largura de 8. Da mesma forma, System.out.printf ().
NomadMaker

Respostas:


169

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


Eu tentei esse método. No meu caso, li o byte de um arquivo binário e o armazenei na matriz de bytes B. Eu uso System.out.println(Integer.toBinaryString(B[i])). Quando eu uso esses métodos, o problema é (a) quando os bits começam com (mais à esquerda) 1, a saída não está correta porque converte B[i]para um valor int negativo. (b) se os bits começam com 0, a saída ignora 0, por exemplo, assume que B[0]tem 00000001, a saída é em 1vez de00000001
Sean

1
@Sean: a) acontece porque a byteem Java é um inteiro complemento de dois com sinal de 8 bits. Seu valor mínimo é -128 (2 ^ 8) e seu valor máximo é 127; b) Você pode corrigir isso facilmente usando isso String.format("%8s", Integer.toBinaryString(b)).replace(' ', '0')para preencher à esquerda a string resultante com zeros.
João Silva

1
@ João: obrigado pelo seu conselho. Você tem alguma ideia sobre como endereçar (a), como armazenar o formato de bit original (começa com 1) na string?
Sean,

1
@Sean: Sim, apenas &com 0xFF.
João Silva

11
@Sean: & 0xFFbasicamente converte um signed byteem um unsigned integer. Por exemplo, -129como você disse, é representado por 11111111111111111111111110000001. Nesse caso, você basicamente deseja os primeiros 8 bits (menos significativos), então faça o AND ( &) com 0xFF( 00000000000000000000000011111111), limpando efetivamente os 1's à esquerda com os quais não nos importamos, deixando apenas 10000001.
João Silva

32

Eu usei isso. Ideia semelhante a outras respostas, mas não vi a abordagem exata em qualquer lugar :)

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

0xFFé 255 ou 11111111(valor máximo para um byte sem sinal). 0x100é 256, ou100000000

O &upcasts o byte para um inteiro. Nesse ponto, pode ser qualquer coisa de 0- 255( 00000000a 11111111, excluí os 24 bits principais). + 0x100e .substring(1)garantir que haverá zeros à esquerda.

Eu cronometrei em comparação com a resposta de João Silva , e isso é mais de 10 vezes mais rápido. http://ideone.com/22DDK1 Não incluí a resposta de Pshemo porque ela não preenche corretamente.


Ei! tenho uma pergunta sobre isso. Eu tenho uma string de representação Base64 de um PDF, preciso converter em binário. Basicamente, Base64-> byte-> binary. Este código funcionará?
Sid

O que exatamente o + 0x100 faz? Você está adicionando 256 ao inteiro resultante, mas por quê?
Conner Dassen

1
@ConnerDassen Garante que a string binária seja preenchida com 0. Por exemplo, se bfor 1, sem + 0x100você receberá apenas "1"como sua string. Adicionando 1, você obtém 100000001, e se você pegar a substring ignorando o primeiro caractere, você obterá o apropriado "00000001". Se você não quiser que sua corda seja acolchoada, você pode simplesmente usar Integer.toBinaryString(b & 0xff). O & 0xffcorrige os problemas de complemento do negativo / dois
Raekye

8

É isso que você está procurando?

conversão de string para byte

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

convertendo de byte em string

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

Ou, como João Silva disse em seu comentário para adicionar entrelinha 0, podemos formatar string com comprimento de 8 e substituir os espaços iniciais resultantes por zero, então no caso de string como " 1010"obteremos"00001010"

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

5

Você poderia verificar cada bit no byte e então acrescentar 0 ou 1 a uma string. Aqui está um pequeno método auxiliar que escrevi para teste:

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

Obtenha cada bit de byte e converta em string. Digamos que o byte tenha 8 bits, e podemos obtê-los um a um por meio do movimento de bits. Por exemplo, movemos o segundo bit do byte 6 bits para a direita, o segundo bit no último bit de 8 bits e, em seguida, (&) com 0x0001 para limpar os bits da frente.

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

Você poderia editar sua resposta para explicar por que esse código responde à pergunta? Respostas apenas em código são desencorajadas , porque não ensinam a solução.
DavidPostill

2

Este código irá demonstrar como um java int pode ser dividido em seus 4 bytes consecutivos. Podemos então inspecionar cada byte usando métodos Java em comparação com a interrogação de byte / bit de baixo nível.

Esta é a saída esperada quando você executa o código abaixo:

[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

Aqui está o código a ser executado:

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

Desculpe, eu sei que é um pouco tarde ... Mas eu tenho uma maneira muito mais fácil ... Para string binária:

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

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

Todos nós sabemos que Java não fornece nada parecido com a palavra-chave unsigned. Além disso, uma byteprimitiva de acordo com as especificações do Java representa um valor entre −128e 127. Por exemplo, se a bytefor castpara um intJava, interpretará o primeiro bitcomo signe usará a extensão de sinal.

Então, como converter um byte maior que 127em sua representação em string binária ??

Nada impede que você veja um bytesimplesmente como 8 bits e interprete esses bits como um valor entre 0e 255. Além disso, você precisa ter em mente que não há nada que você possa fazer para forçar sua interpretação sobre o método de outra pessoa. Se um método aceita um byte, então esse método aceita um valor entre −128e, a 127menos que seja explicitamente declarado de outra forma.

Portanto, a melhor maneira de resolver isso é converter o bytevalor em um intvalor chamando o Byte.toUnsignedInt()método ou convertendo-o em um intprimitivo (int) signedByte & 0xFF. Aqui você tem um exemplo:

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

Resultado

8-bit header:
10000000
11100010
01100000
11101010

0

Você pode trabalhar com BigInteger como o exemplo abaixo, mais especialmente se tiver 256 bits ou mais:

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

Outro exemplo que aceita 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

Você também pode trabalhar para converter o formato Binário para Byte

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

Nota: Para formatação de string para o seu formato binário, você pode usar o exemplo abaixo

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

0

Uma resposta simples poderia 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

-1

Apenas supondo aqui, mas se você tiver um Byte, então não poderia simplesmente invocar toString () no objeto para obter o valor? Ou, olhando para a api , usando byteValue ()?

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.