将字符串转换为二进制?

3

好的,一个朋友帮我稍微修改了这个代码。我理解其他部分的功能以及为什么要这样做,但有一点我不明白。这个128是从哪里来的?此外,该程序会运行,从文件中提取字符串并将其转换为二进制,但会去掉所有空格,因此当你将二进制重新转换为字符串时,它就变成了一个单词。那么这个128是什么意思?我该如何保留空格?

/******************************* *我已经解决了,感谢你们的帮助!* *我改变了代码,所以你可以看到我如何解决它。* *******************************/

         public static void main(String[] args) {

          String text = "My string to binary works too";

          byte[] bytes = text.getBytes();
          StringBuilder binary = new StringBuilder();

          for (byte b : bytes){
            int val = b;
          for (int i = 0; i < 8; i++){
            binary.insert(0, (val & 1) == 0 ? 0 : 1);
            val >>>= 1;
          }
            binary.insert(0, ' ');
         System.out.print(binary);
      }



      }

}


最高的二进制值不是128吗? - Joey
1
@Turix使用空格作为分隔符来调用Scannernext()方法,这就是为什么他会丢失空格。 - Steve P.
@SteveP。啊哈。谢谢你指出来。现在我明白他在问什么了。 - Turix
那么我该怎么做才能消除这个问题呢?(即 .next() 的问题) - Joey
如果你不介意的话,我是一位新手程序员。哈哈 - Joey
显示剩余4条评论
3个回答

1

128是2的7次方,意味着在二进制中它是10000000。字节由8个位组成。因此,在使用128的行上,您正在执行按位与操作以获取最高位。(然后在下一行,您将该值向左移动一个位并重复,以依次从左到右获取每个位值。)


1
@Joey 作为参考,你失去了空格是因为你使用了 Scanner 中的 next() 方法,它使用空格作为分隔符。 - Steve P.
1
@Basilevs 一个数字的最高位通常是符号位。但在这种情况下,他只是将字符转换为二进制字节,而不是尝试获取它们的数值。 (并且假设他正在使用ASCII字符,最高位始终为0。) - Turix
还是不要呢?如果128是MSB,符号放在哪里?此外,问题说明应该可以进行反向转换,因此获取值而不丢失位很重要。对ASCII的假设现在也不好闻。 - Basilevs
1
@Basilevs 为了明确起见,他的代码将能够正常工作(即打印出正确的字符二进制表示),无论它们是 ASCII 还是其他编码,也不受字节的有符号/无符号状态的影响。 - Turix
@Basilevs 一个字节是8位,这意味着它可以很好地容纳二进制10000000。 - Turix
显示剩余10条评论

0
正如其他人所说,128只是最高有效位上为1的位掩码。
按照逻辑,如果有一个字节为10011001:
10011001 & 10000000 = 10000000 != 0
11011001 << 1 = 00110010
00110010 & 10000000 = 00000000 == 0

and so on...

这里有一种替代逻辑,它实现了相同的功能但是反过来(在最低有效位中进行掩码操作),并且可能更容易理解:

int val = b;
for (int i = 0; i < 8; i++)
{
    binary.insert(0, (val & 1) == 0 ? 0 : 1);
    val >>>= 1;
}
binary.insert(0, ' ');

按照这个逻辑,你会得到:

10011001 & 00000001 = 00000001 != 0
11011001 >>> 1 = 01101100
01101100 & 00000001 = 00000000 == 0

and so on...

不客气。:)虽然我理解使用128的意义,但对我来说使用1更有意义,并且适用于任何字长。128仅适用于一个字节。 - Radiodef
不必插入空格,有人建议完全不使用Scanner。InputStream正是为此而存在的。 - Basilevs
@Basilevs 是的,使用 InputStream 更为直接。如果使用原始的 FileInputStream,也可以避免读取 String 的需要,因为 OP 可以直接使用读取的字节。 - Radiodef

0
128在二进制中是10000000,因此它是字节的最高有效位(MSB)。 MSB是从左边开始的第一个位。由于代码从MSB到LSB打印位,每个循环迭代根据与仅设置了MSB位(128)的值进行AND(&)的结果打印1或0,并将值向左移动一位。

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