Cách chuyển một byte thành biểu diễn chuỗi nhị phân của nó


92

Ví dụ, các bit trong một byte B10000010, làm thế nào tôi có thể gán các bit vào chuỗi strtheo nghĩa đen, tức là str = "10000010".

Biên tập

Tôi đọc byte từ một tệp nhị phân và được lưu trữ trong mảng byte B. Tôi sử dụng System.out.println(Integer.toBinaryString(B[i])). vấn đề là

(a) khi các bit bắt đầu bằng (ngoài cùng bên trái) 1, đầu ra không đúng vì nó chuyển đổi B[i]thành giá trị int âm.

(b) nếu các bit bắt đầu bằng 0, đầu ra bỏ qua 0, ví dụ: giả sử B[0]có 00000001, đầu ra 1thay vì00000001


2
Tôi bối rối; đây có phải là một thủ thuật?
Dave Newton

1
Bạn đang hỏi làm thế nào để chuyển đổi a bytethành một chuỗi trong cơ số 2?
SLaks

Tôi chỉ cần thêm một câu trả lời cho một thread để làm điều này (chuyển đổi một giá trị cho một chuỗi các số nhị phân) mà làm việc cho Boolean, Byte, Short, Char, Int, và Long. stackoverflow.com/a/54950845/501113
hỗn loạn3 trạng thái cân bằng

Chuỗi # Format () có thể xử lý điều này, nếu bạn yêu cầu nó sử dụng chiều rộng là 8. Tương tự như vậy System.out.printf ().
NomadMaker

Câu trả lời:


170

Sử dụng 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 .


Tôi đã thử phương pháp này. Trong trường hợp của tôi, tôi đọc byte từ tệp nhị phân và được lưu trữ trong mảng byte B. Tôi sử dụng System.out.println(Integer.toBinaryString(B[i])). Khi tôi sử dụng các phương pháp này, vấn đề là (a) khi các bit bắt đầu bằng (ngoài cùng bên trái) 1, đầu ra không đúng vì nó chuyển đổi B[i]thành giá trị int âm. (b) nếu các bit bắt đầu bằng 0, đầu ra bỏ qua 0, ví dụ, giả sử B[0]00000001, đầu ra 1thay vì00000001
Sean

1
@Sean: a) xảy ra vì a bytetrong Java là số nguyên bổ sung 8 bit có dấu của hai. Giá trị nhỏ nhất của nó là -128 (2 ^ 8), và giá trị lớn nhất của nó là 127; b) Bạn có thể dễ dàng khắc phục điều đó bằng cách sử dụng điều này String.format("%8s", Integer.toBinaryString(b)).replace(' ', '0')để đệm chuỗi kết quả bằng các số không.
João Silva

1
@ João: cảm ơn lời khuyên của bạn. Bạn có ý kiến ​​gì về cách đánh địa chỉ (a), cách lưu định dạng bit gốc (bắt đầu bằng 1) vào chuỗi không?
Sean

1
@Sean: Vâng, chỉ &nó với 0xFF.
João Silva

12
@Sean: & 0xFFvề cơ bản chuyển đổi a signed bytethành an unsigned integer. Ví dụ, -129như bạn đã nói, được đại diện bởi 11111111111111111111111110000001. Trong trường hợp này, về cơ bản bạn muốn 8 bit đầu tiên (ít quan trọng nhất), vì vậy bạn VÀ ( &) nó với 0xFF( 00000000000000000000000011111111), làm sạch hiệu quả số 1 ở bên trái mà chúng tôi không quan tâm, chỉ bỏ đi 10000001.
João Silva

34

Tôi đã sử dụng cái này. Ý tưởng tương tự với các câu trả lời khác, nhưng không thấy cách tiếp cận chính xác ở đâu :)

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

0xFFlà 255, hoặc 11111111(giá trị tối đa cho một byte không dấu). 0x100là 256, hoặc100000000

Các &upcasts byte để một số nguyên. Tại thời điểm đó, nó có thể là bất kỳ thứ gì từ 0- 255( 00000000đến 11111111, tôi đã loại trừ 24 bit đầu tiên). + 0x100.substring(1)đảm bảo sẽ có các số 0 đứng đầu.

Tôi đã tính thời gian so với câu trả lời của João Silva , và điều này nhanh hơn gấp 10 lần. http://ideone.com/22DDK1 Tôi không bao gồm câu trả lời của Pshemo vì nó không đúng.


Chào! có một câu hỏi về điều này. Tôi có một chuỗi biểu diễn Base64 của một tệp PDF, tôi cần chuyển đổi thành Binary. Về cơ bản, Base64-> byte-> binary. Mã này có hoạt động không?
Sid

Chính xác thì + 0x100 làm gì? Bạn đang thêm 256 vào số nguyên kết quả, nhưng tại sao?
Conner Dassen

1
@ConnerDassen Nó đảm bảo rằng chuỗi nhị phân là 0 được đệm. Ví dụ, nếu b1, nếu không, + 0x100bạn sẽ chỉ nhận được "1"dưới dạng chuỗi của bạn. Bằng cách thêm 1, bạn sẽ nhận được 100000001, và nếu bạn lấy chuỗi con bỏ qua ký tự đầu tiên, bạn sẽ nhận được thích hợp "00000001". Nếu bạn không muốn chuỗi của bạn được đệm, bạn có thể chỉ cần sử dụng Integer.toBinaryString(b & 0xff). Các giải pháp & 0xffkhắc phục các vấn đề bổ sung tiêu cực / hai
Raekye

8

Đây có phải là những gì bạn đang tìm kiếm?

chuyển đổi từ Chuỗi thành byte

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

chuyển đổi từ byte sang chuỗi

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

Hoặc như João Silva đã nói trong nhận xét của anh ấy để thêm phần dẫn đầu, 0chúng tôi có thể định dạng chuỗi thành độ dài 8 và thay thế các khoảng trống ở đầu kết quả bằng 0, vì vậy trong trường hợp chuỗi như vậy, " 1010"chúng tôi sẽ nhận được"00001010"

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

6

Bạn có thể kiểm tra từng bit trên byte sau đó nối thêm 0 hoặc 1 vào một chuỗi. Đây là một phương pháp trợ giúp nhỏ mà tôi đã viết để thử nghiệm:

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

Nhận từng bit của byte và chuyển đổi thành chuỗi. Giả sử byte có 8 bit, và chúng ta có thể lấy từng bit một thông qua di chuyển bit. Ví dụ, chúng ta di chuyển bit thứ hai của byte 6 bit sang phải, bit thứ hai ở cuối bit 8 bit, sau đó và (&) với 0x0001 để xóa các bit phía trước.

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

Bạn có thể vui lòng chỉnh sửa câu trả lời của mình để giải thích tại sao mã này trả lời câu hỏi không? Câu trả lời chỉ có mã không được khuyến khích vì chúng không dạy giải pháp.
DavidPostill

2

Đoạn mã này sẽ chứng minh cách một int java có thể được chia thành 4 byte liên tiếp của nó. Sau đó, chúng ta có thể kiểm tra từng byte bằng các phương pháp Java so với việc thẩm vấn byte / bit mức thấp.

Đây là kết quả mong đợi khi bạn chạy mã dưới đây:

[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

Đây là mã để chạy:

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

Xin lỗi, tôi biết điều này hơi muộn ... Nhưng tôi có một cách dễ dàng hơn nhiều ... Đối với chuỗi nhị phân:

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

Phương thức 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();
}

1

Bạn có thể làm việc với BigInteger như ví dụ dưới đây, đặc biệt nhất nếu bạn có 256 bit trở lên:

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

Một ví dụ khác chấp nhận byte:

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

Kết quả:

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

binary: 101010001101000011001010010000001100111011010010111001001101100001000000110111101101110001000000111010001101000011001010010000001110010011001010110010000100000011001000111001001100101011100110111001100101110
hex: 546865206769726c206f6e20746865207265642064726573732e

Bạn cũng có thể làm việc để chuyển đổi định dạng Binary sang Byte

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

Lưu ý: Để định dạng chuỗi cho định dạng Nhị phân của bạn, bạn có thể sử dụng mẫu dưới đây

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

1

Một câu trả lời đơn giản có thể là:

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

Chúng ta đều biết rằng Java không cung cấp bất cứ thứ gì giống như từ khóa unsigned. Hơn nữa, một bytenguyên thủy theo thông số của Java đại diện cho một giá trị giữa −128127. Ví dụ: nếu a bytecastđối với intJava sẽ diễn giải đầu tiên bitsignphần mở rộng dấu và sử dụng.

Sau đó, làm thế nào để chuyển đổi một byte lớn hơn 127thành biểu diễn chuỗi nhị phân của nó ??

Không có gì ngăn cản bạn xem byteđơn giản là 8-bit và giải thích các bit đó như một giá trị giữa 0255. Ngoài ra, bạn cần lưu ý rằng bạn không thể làm gì để buộc diễn giải của mình theo phương pháp của người khác. Nếu một phương thức chấp nhận a byte, thì phương thức đó chấp nhận một giá trị giữa −128127trừ khi được nêu rõ ràng khác.

Vì vậy, cách tốt nhất để giải quyết điều này là chuyển đổi bytegiá trị thành một intgiá trị bằng cách gọi Byte.toUnsignedInt()phương thức hoặc ép intkiểu nguyên thủy (int) signedByte & 0xFF. Ở đây bạn có một ví dụ:

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

Đầu ra

8-bit header:
10000000
11100010
01100000
11101010

-1

Chỉ đoán ở đây thôi, nhưng nếu bạn có Byte thì bạn không thể chỉ gọi toString () trên đối tượng để nhận giá trị? Hoặc, nhìn lướt qua api , sử dụng byteValue ()?

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.