Bir baytı ikili dize gösterimine dönüştürme


96

Örneğin, bir bayt içinde bitleri Bvardır 10000010, ben dizeye bit atayabilirsiniz nasıl strolduğunu tam anlamıyla, str = "10000010".

Düzenle

Baytı ikili bir dosyadan okudum ve bayt dizisinde sakladım B. Ben kullanıyorum System.out.println(Integer.toBinaryString(B[i])). problem şu

(a) bitler (en soldaki) 1 ile başladığında, B[i]negatif bir int değerine dönüştüğü için çıktı doğru değildir .

(b) bitler ile başlıyorsa 0, çıktı yok sayılır, 0örneğin, B[0]00000001 olduğunu varsayarsak , çıktı 1yerine00000001


2
Kafam karıştı; bu bir numara mı?
Dave Newton

1
byte2 tabanındaki bir dizgeye nasıl dönüştürüleceğini mi soruyorsunuz ?
SLaks

Sadece için çalışır (ikili basamak String bir değer dönüştürme) Bunu yapmak için başka bir iş parçacığı bir cevap eklendi Boolean, Byte, Short, Char, Int, ve Long. stackoverflow.com/a/54950845/501113
chaotic3quilibrium

String # Format (), 8 genişliğini kullanmasını söylediyseniz, bunu halledebilir. Aynı şekilde System.out.printf ().
NomadMaker

Yanıtlar:


174

Kullanım 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 .


Bu yöntemi denedim. Benim durumumda, baytı ikili bir dosyadan okudum ve bayt dizisinde sakladım B. Ben kullanıyorum System.out.println(Integer.toBinaryString(B[i])). Bu yöntemleri kullandığımda, sorun (a) bitler (en soldaki) 1 ile başladığında, çıktı doğru değil çünkü B[i]negatif bir int değerine dönüşüyor . bit 0 ile başlar (b), çıkış göz ardı 0kabul örneğin B[0]vardır 00000001, çıkış 1yerine00000001
Sean

1
@Sean: a) byteJava'da a 8-bitlik işaretli ikinin tümleyen tamsayısı olduğu için olur. Minimum değeri -128 (2 ^ 8) ve maksimum değeri 127; b) String.format("%8s", Integer.toBinaryString(b)).replace(' ', '0')Elde edilen dizeyi sıfırlarla sol tuşa koymak için bunu kullanarak bunu kolayca düzeltebilirsiniz .
João Silva

1
@ João: Tavsiyen için teşekkürler. (A) 'yı nasıl adresleyeceğiniz, orijinal bit biçimini (1 ile başlar) dizeye nasıl kaydedeceğiniz hakkında bir fikriniz var mı?
Sean

1
@Sean: Evet, sadece &onunla 0xFF.
João Silva

14
@Sean: & 0xFFtemelde a'yı signed bytebir unsigned integer. Örneğin, -129dediğin gibi, ile temsil edilir 11111111111111111111111110000001. Bu durumda, temelde ilk (en az önemli) 8 biti istiyorsunuz, bu nedenle VE ( &) ile 0xFF( 00000000000000000000000011111111), umursamadığımız soldaki 1'leri etkili bir şekilde temizleyerek, sadece dışarıda bırakarak 10000001.
João Silva

37

Bunu kullandım. Diğer cevaplarla benzer fikir, ancak hiçbir yerde tam yaklaşımı göremedim :)

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

0xFF255 veya 11111111(işaretsiz bayt için maksimum değer). 0x100256 veya100000000

&Bir tamsayıya bayt upcasts. Bu noktada, bu bir şey olabilir 0- 255( 00000000için 11111111, ben lider 24 bit hariç). + 0x100ve .substring(1)başında sıfır olacağından emin olun.

João Silva'nın cevabına kıyasla zamanını belirledim ve bu 10 kat daha hızlı. http://ideone.com/22DDK1 Pshemo'nun yanıtını düzgün doldurmadığı için eklemedim.


Hey! bununla ilgili bir sorum var. Bir PDF'nin Base64 gösterim dizisine sahibim, İkili'ye dönüştürmem gerekiyor. Temel olarak, Base64-> bayt-> ikili. Bu kod çalışacak mı?
Sid

+ 0x100 tam olarak ne yapar? Ortaya çıkan tam sayıya 256 ekliyorsunuz, ama neden?
Conner Dassen

1
@ConnerDassen İkili dizgenin 0 dolgulu olmasını sağlar. Örneğin, eğer öyleyse b, siz 1olmadan + 0x100sadece dizeniz "1"olarak alırsınız . Ekleyerek 1, elde 100000001edersiniz ve alt dizeyi ilk karakteri göz ardı ederek alırsanız, doğru olanı elde edersiniz "00000001". İpinizin doldurulmasını istemiyorsanız, basitçe kullanabilirsiniz Integer.toBinaryString(b & 0xff). & 0xffDüzeltmeleri negatif / ikinin tamamlayıcı sorunları
Raekye

9

Aradığınız bu mu?

String'den bayta dönüştürme

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

bayttan dizeye dönüştürme

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

Ya da João Silva'nın satır başı eklemek için yorumunda söylediği gibi, 0dizeyi 8 uzunluğa biçimlendirebiliriz ve sonuçta ortaya çıkan öndeki boşlukları sıfırla değiştirebiliriz, bu nedenle aşağıdaki gibi bir dize durumunda " 1010"elde ederiz"00001010"

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

6

Bayttaki her biti kontrol edebilir ve ardından bir dizeye 0 veya 1 ekleyebilirsiniz. İşte test için yazdığım küçük bir yardımcı yöntem:

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

Her bir bayt parçasını alın ve dizeye dönüştürün. Diyelim ki baytın 8 biti var ve bunları birer birer bit hareketiyle elde edebiliriz. Örneğin, ön bitleri temizlemek için 6 bitlik baytın ikinci bitini sağa, ikinci biti 8 bitlik bitten sonra ve (&) 0x0001 ile hareket ettiririz.

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

Bu kodun soruyu neden yanıtladığını açıklamak için lütfen yanıtınızı düzenler misiniz ? Çözümü öğretmedikleri için yalnızca kod yanıtları tavsiye edilmez .
DavidPostill

2

Bu kod, bir java int'in 4 ardışık bayta nasıl bölünebileceğini gösterecektir. Daha sonra, düşük seviyeli bayt / bit sorgulamasına kıyasla Java yöntemlerini kullanarak her baytı inceleyebiliriz.

Aşağıdaki kodu çalıştırdığınızda beklenen çıktı budur:

[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

Çalıştırılacak kod şu şekildedir:

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

Üzgünüm, bunun biraz geç olduğunu biliyorum ... Ama çok daha kolay bir yolum var ... İkili dizgiye:

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

getCorrectBits yöntemi:

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

1

BigInteger ile aşağıdaki örnekte olduğu gibi çalışabilirsiniz , özellikle 256 bit veya daha uzun bir süreniz varsa :

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

Bayt kabul eden başka bir örnek:

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

Sonuç:

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

binary: 101010001101000011001010010000001100111011010010111001001101100001000000110111101101110001000000111010001101000011001010010000001110010011001010110010000100000011001000111001001100101011100110111001100101110
hex: 546865206769726c206f6e20746865207265642064726573732e

Ayrıca dönüştürmek için çalışabilir Binary için Bayt formatında

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

Not: İkili biçiminizin dize biçimlendirmesi için aşağıdaki örneği kullanabilirsiniz

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

1

Basit bir cevap şöyle olabilir:

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

0

Hepimiz Java'nın işaretsiz anahtar kelime gibi bir şey sağlamadığını biliyoruz. Dahası, byteJava'nın özelliklerine göre bir ilkel , −128ve arasındaki bir değeri temsil eder 127. Örneğin, bir eğer byteolduğunu castbir etmek intJava ilk yorumlayacak bitolarak signve kullanım işareti uzantısı.

Daha sonra, bir baytı 127ikili dizge gösterimine nasıl dönüştürür ?

Hiçbir şey sizi byte8 bit olarak görmenizi ve bu bitleri 0ve arasındaki bir değer olarak yorumlamanızı engellemez 255. Ayrıca, yorumunuzu başka birinin yöntemine dayatmak için yapabileceğiniz hiçbir şey olmadığını da aklınızda bulundurmalısınız. Bir yöntem a'yı kabul ederse byte, o zaman bu yöntem , aksi açıkça belirtilmedikçe −128ve arasında bir değer kabul eder 127.

Dolayısıyla, bunu çözmenin en iyi yolu , yöntemi çağırarak veya onu ilkel olarak çevirerek değeri bytebir intdeğere dönüştürmektir . İşte bir örnek var: Byte.toUnsignedInt()int(int) signedByte & 0xFF

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

Çıktı

8-bit header:
10000000
11100010
01100000
11101010

0

Baytları toplu olarak ikili dizelere dönüştürmesi gerekenler için bir başka ipucu: Bu String işlemini her zaman kullanmak yerine bir arama tablosu kullanın. Bu, dönüştürme işlevini tekrar tekrar çağırmaktan çok daha hızlıdır

public class ByteConverterUtil {

  private static final String[] LOOKUP_TABLE = IntStream.range(0, Byte.MAX_VALUE - Byte.MIN_VALUE + 1)
                                                        .mapToObj(intValue -> Integer.toBinaryString(intValue + 0x100).substring(1))
                                                        .toArray(String[]::new);

  public static String convertByte(final byte byteValue) {
    return LOOKUP_TABLE[Byte.toUnsignedInt(byteValue)];
  }

  public static void main(String[] args){
    System.out.println(convertByte((byte)0)); //00000000
    System.out.println(convertByte((byte)2)); //00000010
    System.out.println(convertByte((byte)129)); //10000001
    System.out.println(convertByte((byte)255)); //11111111
  }


}

-1

Burada sadece tahmin ediyorum, ancak bir Baytınız varsa, değeri elde etmek için nesne üzerinde toString () 'i çağıramaz mıydınız? Ya da bakarak API byteValue kullanarak ()?

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.