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

Sean
fonte
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 .

João silva
fonte
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.

Raekye
fonte
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'));
Pshemo
fonte
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();
}
Martyn
fonte
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();
}
Jamee
fonte
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() );
    }

}
Naresh Maharaj
fonte
2
Integer.toBinaryString((byteValue & 0xFF) + 256).substring(1)
Timofey Gorshkov
fonte
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;
}
Jp Silver
fonte
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
fonte
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
Teocci
fonte
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
Josef Panerio
fonte
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
Daniel De León
fonte
-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 ()?

geogaddi
fonte