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

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

245951 次浏览

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

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

这就是你要找的吗?

converting from String to byte

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

converting from byte to String

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

或者正如 João Silva 在他的评论中所说,我们可以将字符串格式化为长度8,并将结果的前导空格替换为零,所以在字符串如 " 1010"的情况下,我们将得到 "00001010"

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

I used this. Similar idea to other answers, but didn't see the exact approach anywhere :)

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

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

&将字节向上转换为整数。在这一点上,它可以是任何从 0-255(0000000011111111,我排除了前24位)。+ 0x100.substring(1)确保有前导零。

我计算了它和 João Silva 的回答的时间,这个比 João Silva 的回答快10倍。我没有包括 Pshemo 的答案,因为它没有适当垫。

这段代码将演示如何将一个 javaint 分解为它连续的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

Here is the code to run:

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


}

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

Get each bit of byte and convert to string. 假设字节有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();
}
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();
}

对不起,我知道这有点晚了... 但我有一个更简单的方法..。 To binary string :

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

Get纠正位方法:

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;
}
Integer.toBinaryString((byteValue & 0xFF) + 256).substring(1)

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

那么,如何将一个大于 127的字节转换为它的二进制字符串表示形式呢?

没有什么可以阻止您将 byte简单地视为8位,并将这些位解释为 0255之间的值。另外,你需要记住,你不能强迫别人用你的方法来解释。如果一个方法接受一个 byte,那么该方法接受一个介于 −128127之间的值,除非另有明确说明。

因此,解决这个问题的最佳方法是通过调用 Byte.toUnsignedInt()方法或将其强制转换为 int基元 (int) signedByte & 0xFF来将 byte值转换为 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

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

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

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

A simple answer could be:

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

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

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
}




}