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


92

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

编辑

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

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

(b)如比特首先0,输出忽略0,例如,假设B[0]有00000001,则输出为1代替00000001


2
我很困惑; 这是把戏吗?
戴夫牛顿

1
您是否在问如何将a转换为byte以2为底的字符串?
SLaks 2012年

我只是增加了一个答案,另一个线程这样做(的值转换为二进制数字字符串),它适用于BooleanByteShortCharInt,和Longstackoverflow.com/a/54950845/501113
chaotic3quilibrium

如果您告诉String#Format()使用8的宽度,则它可能能够处理此问题。同样,System.out.printf()。
NomadMaker

Answers:


169

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


我尝试过这种方法。就我而言,我从二进制文件读取字节,并将其存储在字节数组中B。我用System.out.println(Integer.toBinaryString(B[i]))。当我使用此方法时,问题是(a)当位以(最左边)1开头时,输出不正确,因为它将转换B[i]为负int值。(b)如位从0开始,输出忽略0,例如,假定B[0]00000001,输出1代替00000001
肖恩

1
@Sean:a)发生是因为byteJava中的a 是一个8位带符号的二进制补码整数。最小值为-128(2 ^ 8),最大值为127; b)您可以轻松地解决此问题,方法是使用此String.format("%8s", Integer.toBinaryString(b)).replace(' ', '0')命令将生成的字符串用零填充。
若昂Silva的

1
// @João:谢谢你的建议。您是否有关于如何寻址(a),如何将原始位格式(从1开始)存储到字符串中的想法?
肖恩2012年

1
@Sean:是的,仅&此而已0xFF
若昂Silva的

11
@Sean:& 0xFF基本上将a转换signed byteunsigned integer。例如,-129就像您所说的那样,用表示11111111111111111111111110000001。在这种情况下,您基本上需要第一个(最低有效)8位,因此您可以将&它与0xFF00000000000000000000000011111111)进行AND()操作,从而有效地清除了我们不关心的左侧的1,只剩下了10000001
若昂Silva的

32

我用这个 与其他答案类似的想法,但是在任何地方都没有找到确切的方法:)

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

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

&字节向上转换为整数。在那一点上,它可以是0- 2550000000011111111,我不包括前24位)。+ 0x100.substring(1)确保前导零。

JoãoSilva的回答相比,我给它定了时间,并且快10倍以上。http://ideone.com/22DDK1我没有包括Pshemo的答案,因为它无法正确填充。


嘿!有一个问题。我有PDF的Base64表示字符串,我需要转换成Binary。基本上是Base64-> byte-> binary。这段代码会起作用吗?
2016年

+ 0x100到底是做什么的?您要将256添加到结果整数中,但是为什么呢?
Conner Dassen

1
@ConnerDassen确保二进制字符串填充为0。例如,如果b1,则没有+ 0x100您将仅"1"作为字符串。通过添加1,您会得到100000001,如果忽略子字符串而忽略第一个字符,您将获得正确的字符"00000001"。如果您不想填充字符串,则可以使用Integer.toBinaryString(b & 0xff)。该& 0xff修复的负面/补问题
Raekye

8

这是你想要的?

从字符串转换为字节

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ãoSilva在他的评论中所说,添加前导,0我们可以将字符串格式设置为长度8,并将结果前导空格替换为零,因此在出现字符串的情况下," 1010"我们将得到"00001010"

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

5

您可以检查字节上的每个位,然后将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();
}

3

获取字节的每一位并转换为字符串。假设一个字节有8位,我们可以通过位移动来一一获取。例如,我们将字节的第二位向右移动6位,第二位移至8位的最后一位,然后将and(&)与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

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

}


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

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

0

我们都知道Java不提供unsigned关键字之类的东西。此外,byte根据Java规范的原语表示介于−128和之间的值127。例如,如果Java的a bytecastint它将第一个解释bit为the sign并使用符号扩展名。

然后,如何将大于一个字节的字节转换127为其二进制字符串表示形式?

没有什么可以阻止您将byte简单的8位数据查看并将这些位解释为0和之间的值255。另外,您需要记住,您无能为力以其他人的方法进行解释。如果方法接受byte,则该方法接受到之间的值−128127除非另有明确说明。

因此,解决此问题的最佳方法是通过调用方法或将其强制转换为原始byte值将其转换为值。这里有一个例子: intByte.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);
    }
}

输出量

8-bit header:
10000000
11100010
01100000
11101010

0

您可以像下面的示例一样使用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

0

一个简单的答案可能是:

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

-1

只是在这里猜测,但是如果您有一个字节,那么您不能简单地在对象上调用toString()来获取值吗?或者,使用byteValue()浏览api

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.