如何将一个字节转换为其二进制字符串表示形式?

118

例如,一个字节 B 中的位是 10000010,我该如何将这些位字面上分配给字符串 str,即 str = "10000010"

编辑

我从二进制文件中读取了字节,并将其存储在字节数组 B 中。我使用 System.out.println(Integer.toBinaryString(B[i]))。问题是

(a) 当位以 (最左侧的) 1 开头时,输出不正确,因为它将 B[i] 转换为负整数值。

(b) 如果位以 0 开头,则输出会忽略 0,例如,假设 B[0] 为 00000001,则输出为 1 而不是 00000001


2
我很困惑,这是个诡计吗? - Dave Newton
1
你是在询问如何将一个 byte 转换为二进制字符串吗? - SLaks
我刚刚为另一个线程添加了一个答案,可以将BooleanByteShortCharIntLong类型的值转换为二进制数字字符串。https://dev59.com/WWox5IYBdhLWcg3wFAjW#54950845 - chaotic3quilibrium
如果您告诉 String#Format() 使用 8 的宽度,它可能能够处理这个问题。同样地,System.out.printf() 也可以。 - NomadMaker
14个回答

210

使用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

演示.


3
@Sean:a)这是因为在Java中,一个字节(byte)是一个8位的有符号二进制整数。它的最小值是-128(2的8次方),最大值是127;b)你可以通过使用String.format("%8s", Integer.toBinaryString(b)).replace(' ', '0')将结果字符串左侧填充零来轻松解决这个问题。 - João Silva
1
@ João:谢谢你的建议。你有没有关于如何解决(a)的想法,如何将原始位格式(以1开头)存储到字符串中? - Sean
1
@Sean:是的,只需将其与0xFF进行&操作。 - João Silva
20
& 0xFF 将一个 有符号字节 转换成一个 无符号整数。例如,像你所说的 -129,它被表示为 11111111111111111111111110000001。在这种情况下,你只想要前(最低有效)8位,所以你用 0xFF (00000000000000000000000011111111) 进行了与(&)运算,有效地清除了我们不关心的左侧的1,只留下了 10000001 - João Silva
我认为这个例子可以改进,因为 byte b1 = (byte) 129; 溢出了。 - Mirco Widmer
显示剩余2条评论

47

我用过这个方法。和其他答案的思路相似,但没有在其他地方看到过这种具体的方法 :)

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

0xFF是255,或者11111111(无符号字节的最大值)。 0x100是256,或者100000000

& 将字节升级为整数。此时,它可以是从0255(从0000000011111111,我排除了前导24位)的任何值。 + 0x100.substring(1)确保有前导零。

我将其与João Silva的答案进行了时间比较,这快了10倍以上。http://ideone.com/22DDK1 我没有包含Pshemo的答案,因为它不能正确填充。


嗨!我有一个关于这个问题的疑问。我有一个PDF文件的Base64表示字符串,我需要将其转换为二进制。基本上,是Base64->byte->binary。这段代码能行吗? - Sid
+0x100 到底是做什么用的?您会将 256 添加到结果整数中,但为什么? - Conner Dassen
2
@ConnerDassen 它确保二进制字符串是0填充的。例如,如果b1,没有+ 0x100,你将只得到"1"作为你的字符串。通过添加1,你会得到100000001,如果你忽略第一个字符并取子字符串,你将得到正确的"00000001"。如果你不想让你的字符串被填充,你可以简单地使用Integer.toBinaryString(b & 0xff)& 0xff修复了负数/二进制补码问题。 - Raekye

12

这是您正在寻找的吗?

将字符串转换为字节

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

将字节转换为字符串

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

正如João Silva在他的评论中所说,为了添加前导0,我们可以将字符串格式化为长度为8,并用零替换结果中的前导空格,因此对于像" 1010"这样的字符串,我们将获得"00001010"

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

7

获取每个字节的位并转换为字符串。 假设一个字节有8位,我们可以通过位移逐一获取它们。例如,将字节的第二位向右移动6位,将第二位移到8位的最后一位,然后使用&0x0001清除前面的位。

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

能否请您[编辑]您的答案,解释一下为什么这段代码可以回答问题?仅有代码的答案是不被鼓励的,因为它们无法教授解决方案。 - DavidPostill
我需要一个小端解决方案,而这个是最容易适应的(通过将迭代顺序更改为0->7)。谢谢! - gmk57

7
你可以检查字节上的每一位,然后将0或1附加到字符串中。这是我为测试编写的一个小助手方法:
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();
}

4
您可以按照以下示例使用BigInteger,特别是当您拥有256位或更长的数字时:
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));

另一个接受字节的示例:

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

结果:

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

binary: 101010001101000011001010010000001100111011010010111001001101100001000000110111101101110001000000111010001101000011001010010000001110010011001010110010000100000011001000111001001100101011100110111001100101110
hex: 546865206769726c206f6e20746865207265642064726573732e

您还可以将二进制转换为字节格式

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

注意: 您可以使用以下示例进行二进制格式的字符串格式化

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

2
抱歉,我知道有些晚了...但是我有一个更简单的方法... 转换为二进制字符串:
//Add 128 to get a value from 0 - 255
String bs = Integer.toBinaryString(data[i]+128);
bs = getCorrectBits(bs, 8);

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

2
Integer.toBinaryString((byteValue & 0xFF) + 256).substring(1)

2

这段代码将演示如何将java int拆分成其4个连续的字节。然后,我们可以使用Java方法检查每个字节,与低级字节/位询问进行比较。

当您运行下面的代码时,这是预期的输出:

[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

这是要运行的代码:

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

}

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接