Comment convertir un octet en sa représentation sous forme de chaîne binaire

92

Par exemple, les bits dans un octet Bsont 10000010, comment puis-je attribuer les bits à la chaîne strlittéralement, c'est-à-direstr = "10000010" .

Éditer

J'ai lu l'octet à partir d'un fichier binaire et stocké dans le tableau d'octets B. J'utilise System.out.println(Integer.toBinaryString(B[i])). le problème est

(a) lorsque les bits commencent par (le plus à gauche) 1, la sortie n'est pas correcte car elle convertit B[i] en une valeur int négative.

(b) si les bits commencent par 0, la sortie ignore 0, par exemple, suppose B[0]a 00000001, la sortie est 1au lieu de00000001

Sean
la source
2
Je suis confus; est-ce un truc?
Dave Newton
1
Vous demandez-vous comment convertir un byteen une chaîne en base 2?
SLaks
Je viens d' ajouter une réponse à un autre thread pour ce faire ( la conversion d' une valeur à une chaîne de chiffres binaires) qui fonctionne pour Boolean, Byte, Short, Char, Intet Long. stackoverflow.com/a/54950845/501113
chaotic3quilibrium
String # Format () pourrait être en mesure de gérer cela, si vous lui avez dit d'utiliser une largeur de 8. De même System.out.printf ().
NomadMaker

Réponses:

170

Utilisez 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
la source
J'ai essayé cette méthode. Dans mon cas, j'ai lu l'octet à partir d'un fichier binaire et stocké dans le tableau d'octets B. J'utilise System.out.println(Integer.toBinaryString(B[i])). Lorsque j'utilise ces méthodes, le problème est (a) lorsque les bits commencent par (le plus à gauche) 1, la sortie n'est pas correcte car elle se convertit B[i]en une valeur int négative. (b) si les bits commencent par 0, la sortie ignore 0, par exemple, suppose B[0]a 00000001, la sortie est 1au lieu de00000001
Sean
1
@Sean: a) se produit parce que a byteen Java est un entier de complément à deux signé 8 bits. Sa valeur minimale est -128 (2 ^ 8) et sa valeur maximale est 127; b) Vous pouvez facilement résoudre ce problème en utilisant ceci String.format("%8s", Integer.toBinaryString(b)).replace(' ', '0')pour remplir à gauche la chaîne résultante avec des zéros.
João Silva
1
@ João: merci pour vos conseils. Avez-vous une idée sur la façon d'adresser (a), comment stocker le format de bit d'origine (commence par 1) dans la chaîne?
Sean
1
@Sean: Oui, juste &avec 0xFF.
João Silva
12
@Sean: & 0xFFconvertit essentiellement a signed byteen un unsigned integer. Par exemple, -129comme vous l'avez dit, est représenté par 11111111111111111111111110000001. Dans ce cas, vous voulez fondamentalement les 8 premiers bits (les moins significatifs), donc vous ET ( &) avec 0xFF( 00000000000000000000000011111111), nettoyant efficacement les 1 à gauche dont nous ne nous soucions pas, en laissant juste de côté 10000001.
João Silva
33

J'ai utilisé ça. Idée similaire à d'autres réponses, mais je n'ai vu l'approche exacte nulle part :)

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

0xFFest 255, ou 11111111(valeur maximale pour un octet non signé). 0x100est 256, ou100000000

L' &upcasts l'octet à un entier. À ce stade, cela peut être n'importe quoi de 0- 255( 00000000à 11111111, j'ai exclu les 24 bits de tête). + 0x100et .substring(1)assurez - vous qu'il y aura des zéros non significatifs.

Je l'ai chronométré par rapport à la réponse de João Silva , et c'est 10 fois plus rapide. http://ideone.com/22DDK1 Je n'ai pas inclus la réponse de Pshemo car elle ne remplit pas correctement.

Raekye
la source
Hey! j'ai une question à ce sujet. J'ai une chaîne de représentation Base64 d'un PDF, je dois la convertir en binaire. Fondamentalement, Base64-> byte-> binary. Ce code fonctionnera-t-il?
Sid
Que fait exactement le + 0x100? Vous ajoutez 256 à l'entier résultant, mais pourquoi?
Conner Dassen
1
@ConnerDassen Cela garantit que la chaîne binaire est complétée à 0. Par exemple, si best 1, sans + 0x100vous obtiendrez simplement "1"votre chaîne. En ajoutant 1, vous obtenez 100000001, et si vous prenez la sous-chaîne en ignorant le premier caractère, vous obtiendrez le bon "00000001". Si vous ne voulez pas que votre chaîne soit rembourrée, vous pouvez simplement utiliser Integer.toBinaryString(b & 0xff). Le & 0xffcorrige les problèmes de complément négatif / deux
Raekye
8

Est-ce ce que vous recherchez?

conversion de String en octet

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

conversion d'octet en chaîne

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

Ou comme João Silva l'a dit dans son commentaire pour ajouter le début, 0nous pouvons formater la chaîne à la longueur 8 et remplacer les espaces de début résultants par zéro, donc dans le cas d'une chaîne comme " 1010"nous obtiendrons"00001010"

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

Vous pouvez vérifier chaque bit sur l'octet puis ajouter 0 ou 1 à une chaîne. Voici une petite méthode d'aide que j'ai écrite pour les tests:

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
la source
3

Obtenez chaque bit d'octet et convertissez-le en chaîne. Disons que l'octet a 8 bits, et nous pouvons les obtenir un par un via un mouvement de bits. Par exemple, nous déplaçons le deuxième bit de l'octet 6 bits vers la droite, le deuxième bit au dernier bit de 8 bits, puis et (&) avec 0x0001 pour nettoyer les bits avant.

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
la source
Pourriez-vous s'il vous plaît modifier votre réponse pour expliquer pourquoi ce code répond à la question? Les réponses basées uniquement sur le code sont déconseillées , car elles n'enseignent pas la solution.
DavidPostill
2

Ce code montrera comment un java int peut être divisé en ses 4 octets consécutifs. Nous pouvons ensuite inspecter chaque octet en utilisant des méthodes Java par rapport à une interrogation octet / bit de bas niveau.

Il s'agit de la sortie attendue lorsque vous exécutez le code ci-dessous:

[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

Voici le code à exécuter:

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
la source
2
Integer.toBinaryString((byteValue & 0xFF) + 256).substring(1)
Timofey Gorshkov
la source
2

Désolé, je sais que c'est un peu tard ... Mais j'ai un moyen beaucoup plus simple ... Pour une chaîne binaire:

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

Méthode 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 Argent
la source
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
la source
1

Vous pouvez travailler avec BigInteger comme dans l'exemple ci-dessous, surtout si vous avez 256 bits ou plus:

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 autre exemple qui accepte des octets:

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

Résultat:

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

binary: 101010001101000011001010010000001100111011010010111001001101100001000000110111101101110001000000111010001101000011001010010000001110010011001010110010000100000011001000111001001100101011100110111001100101110
hex: 546865206769726c206f6e20746865207265642064726573732e

Vous pouvez également travailler pour convertir le binaire au format Byte

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

Remarque: pour le formatage de chaîne pour votre format binaire, vous pouvez utiliser l'exemple ci-dessous

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

Une réponse simple pourrait être:

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
la source
0

Nous savons tous que Java ne fournit rien de tel que le mot-clé unsigned. De plus, une byteprimitive selon la spécification Java représente une valeur entre −128et 127. Par exemple, si a byteest castà un intJava, il interprétera le premier bitcomme l' signextension de signe et utilisera.

Ensuite, comment convertir un octet supérieur 127à sa représentation sous forme de chaîne binaire ??

Rien ne vous empêche d'afficher un bytesimplement comme 8 bits et d'interpréter ces bits comme une valeur entre 0et 255. De plus, vous devez garder à l'esprit que vous ne pouvez rien faire pour imposer votre interprétation à la méthode de quelqu'un d'autre. Si une méthode accepte a byte, alors cette méthode accepte une valeur entre −128et127 sauf indication contraire explicite.

La meilleure façon de résoudre ce problème est donc de convertir la bytevaleur en intvaleur en appelant la Byte.toUnsignedInt()méthode ou en la convertissant en intprimitive (int) signedByte & 0xFF. Voici un exemple:

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

Production

8-bit header:
10000000
11100010
01100000
11101010
Teocci
la source
-1

Juste deviner ici, mais si vous avez un Byte, ne pouvez-vous pas simplement invoquer toString () sur l'objet pour obtenir la valeur? Ou, jetant un œil à l' API , en utilisant byteValue ()?

Geogaddi
la source