如何在Java中反转无符号字节的位?

Dav*_*999 16 java unsigned byte bits complement

我正在尝试为非常简单的加密类型编写解码器.通过扫描仪输入0-255的数字,这些位被反转,然后转换为字符并打印.

例如,数字178应转换为字母"M".

178是10110010.

反转所有位应该给出01001101,即77或"M"作为字符.

我遇到的主要问题是,据我所知,Java不支持无符号字节.我可以将值读取为int或short,但由于额外的位,因此在转换期间值将关闭.理想情况下,我可以使用按位补码运算符,但我认为如果我使用带符号数字,我最终会得到负值.关于如何处理这个问题的任何想法?

sta*_*ker 14

我只是使用补码并通过使用二进制和除去其他位.

public class Conv {
    public static void main(String[] args) {
        int val = 178;
        val = ~val & 0xff;
        System.out.println((char) val);
    }
}
Run Code Online (Sandbox Code Playgroud)


sta*_*lue 11

~n & 0xff
Run Code Online (Sandbox Code Playgroud)

~补码并隐式转换为像所有数值运算一样的整数,然后& 0xff屏蔽除低8位以外的所有内容以获得无符号值,再次作为整数.

我首先以不同的方式阅读您的问题,以反转顺序而不是位的值,这就是答案.

你可以使用Integer.reverse()(未经测试):

Integer.reverse(n << 24) & 0xff
Run Code Online (Sandbox Code Playgroud)


Mar*_*ers 6

Java中定义了按位运算,int因此使用int而不是有意义byte。您可以使用Scanner.nextInt,而不是Scanner.nextByte。您应该验证用户的输入,以确保输入的所有整数都在0到255的范围内,如果遇到超出范围的数字,则显示适当的错误消息。

将数字存储在整数中后,要翻转最低有效的8位,可以与0xff进行异或。对于0到255之间的所有输入,这应该可以正常工作:

x ^= 0xff;
Run Code Online (Sandbox Code Playgroud)

例:

String input = "178 0 255";
Scanner s = new Scanner(input);
while (s.hasNextInt()) {
    int x = s.nextInt();
    if (x < 0 || x > 255) {
        System.err.println("Not in range 0-255: " + x);
    } else {
        x ^= 0xff;
        System.out.println(x);
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

77
255
0
Run Code Online (Sandbox Code Playgroud)


Nic*_*cue 0

最简单的方法是三个阶段:

  1. 将值读取为 int(java 中的 32 位)。它可能读作负数,但无论如何我们只关心底部 8 位。int i = scanner.nextByte();
  2. 使用按位运算符将 int 进行反转(正如您所说,会给您 1 作为高位:i = ~i;
  3. 使用逻辑 AND 丢失高位:i = i & 0xFF;

然后将结果用作字符(在java中实际上是16位,但我们只会使用其中的8位):

char c=(char)a;
System.out.println(c); 
Run Code Online (Sandbox Code Playgroud)

全部一起:

int i = scanner.nextByte(); // change this to nextInt() depending on file format
i = ~i;
i = i & 0xFF;
char c=(char)a;
System.out.println(c); 
Run Code Online (Sandbox Code Playgroud)