【问题标题】:How to convert a byte to its binary string representation如何将字节转换为其二进制字符串表示形式
【发布时间】:2012-09-06 23:56:07
【问题描述】:

例如,一个字节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

【问题讨论】:

  • 我很困惑;这是诡计吗?
  • 您是在问如何将byte 转换为以 2 为底的字符串?
  • 我刚刚为另一个线程添加了一个答案(将一个值转换为二进制数字字符串),它适用于BooleanByteShortChar、@ 987654339@ 和 Longstackoverflow.com/a/54950845/501113
  • String#Format() 可能能够处理这个问题,如果你告诉它使用 8 的宽度。同样 System.out.printf()。

标签: java binary byte


【解决方案1】:

使用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
  • @Sean: a) 发生是因为 Java 中的 byte 是一个 8 位有符号二进制补码整数。其最小值为-128(2^8),最大值为127; b)您可以通过使用此String.format("%8s", Integer.toBinaryString(b)).replace(' ', '0') 将结果字符串左填充零来轻松解决此问题。
  • @João:谢谢你的建议。你知道如何寻址(a),如何将原始位格式(以1开头)存储到字符串中吗?
  • @Sean:是的,只需 &0xFF
  • @Sean: & 0xFF 基本上将signed byte 转换为unsigned integer。比如-129,就像你说的,用11111111111111111111111110000001表示。在这种情况下,您基本上想要第一个(最低有效)8 位,因此您将其与0xFF00000000000000000000000011111111)与(&),有效地清除我们不关心的左侧的 1,只省略10000001
【解决方案2】:

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

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

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

& 将字节向上转换为整数。那时,它可以是从0-2550000000011111111,我排除了前 24 位)。 + 0x100.substring(1) 确保会有前导零。

João Silva's answer 相比,我对它进行了计时,这比 João Silva's answer 快了 10 倍以上。 http://ideone.com/22DDK1我没有包含 Pshemo 的答案,因为它没有正确填充。

【讨论】:

  • 嘿!有一个关于这个的问题。我有一个 PDF 的 Base64 表示字符串,我需要转换为二进制。基本上,Base64->byte->binary。这段代码行吗?
  • + 0x100 到底是做什么的?您将 256 添加到结果整数,但为什么呢?
  • @ConnerDassen 确保二进制字符串填充为 0。例如,如果b1,如果没有+ 0x100,您将只得到"1" 作为您的字符串。通过添加1,你会得到100000001,如果你忽略第一个字符,你会得到正确的"00000001"。如果你不希望你的字符串被填充,你可以简单地使用Integer.toBinaryString(b & 0xff)& 0xff 修复了负数/补码问题
【解决方案3】:

这是你要找的吗?

从字符串转换为字节

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      获取字节的每一位并转换为字符串。 假设字节有 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();
      }
      

      【讨论】:

      • 能否请您edit 解释一下为什么这段代码回答了这个问题?纯代码答案是 discouraged,因为它们不教授解决方案。
      • 我需要一个 little-endian 解决方案,而这个最容易适应(通过将迭代顺序更改为 0 -> 7)。谢谢!
      【解决方案6】:

      此代码将演示如何将 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() );
          }
      
      }
      

      【讨论】:

        【解决方案7】:
        Integer.toBinaryString((byteValue & 0xFF) + 256).substring(1)
        

        【讨论】:

          【解决方案8】:

          对不起,我知道这有点晚了...但我有一个更简单的方法... 转为二进制字符串:

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

          【讨论】:

            【解决方案9】:

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

            【讨论】:

              【解决方案10】:
              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();
              }
              

              【讨论】:

                【解决方案11】:

                一个简单的答案可能是:

                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
                

                【讨论】:

                  【解决方案12】:

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

                  那么,如何将大于127的字节转换成它的二进制字符串表示??

                  没有什么可以阻止您将 byte 简单地视为 8 位并将这些位解释为介于 0255 之间的值。此外,您需要记住,您无法将自己的解释强加于其他人的方法。如果一个方法接受 byte,则该方法接受介于 −128127 之间的值,除非另有明确说明。

                  因此,解决此问题的最佳方法是通过调用Byte.toUnsignedInt() 方法或将其转换为int 原语(int) signedByte &amp; 0xFFbyte 值转换为int 值。这里有一个例子:

                  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
                  

                  【讨论】:

                    【解决方案13】:

                    对于那些需要将字节大量转换为二进制字符串的人的另一个提示:使用查找表而不是一直使用那些字符串操作。这比一遍又一遍地调用转换函数要快很多

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

                    【讨论】:

                      【解决方案14】:

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

                      【讨论】:

                        猜你喜欢
                        • 2011-03-27
                        • 2021-02-12
                        • 2015-04-23
                        • 1970-01-01
                        • 1970-01-01
                        • 2021-12-20
                        • 2013-11-26
                        • 2011-01-25
                        相关资源
                        最近更新 更多