18

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

例如,数字 178 应转换为字母“M”。

178 是 10110010。

反转所有位应给出 01001101,即 77 或“M”作为字符。

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

4

7 回答 7

17

我会简单地使用那些补码并通过使用二进制和来摆脱其他位。

public class Conv {
    public static void main(String[] args) {
        int val = 178;
        val = ~val & 0xff;
        System.out.println((char) val);
    }
}
于 2010-07-24T10:42:54.267 回答
12
~n & 0xff

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

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

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

Integer.reverse(n << 24) & 0xff
于 2010-07-24T10:42:23.363 回答
6

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

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

x ^= 0xff;

例子:

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

结果:

77
255
0
于 2010-07-24T10:39:11.523 回答
2

如果 Java 支持这一点,您可以将其读入更大的类型,按位互补,然后对不需要的位进行位屏蔽。

int x = [your byte];
x = ~x & 0xFF;
于 2010-07-24T10:38:54.707 回答
0

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

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

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

char c=(char)a;
System.out.println(c); 

全部一起:

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); 
于 2010-07-24T10:38:22.703 回答
-1

以下是 Java 字节,按二进制表示排序(从 00000000 到 11111111):

0、1、2、..、126、127、-128、-127、..、-2、-1

00000000 为 0,11111111 为 -1

倒数 0 是 -1,倒数 1 是 -2,...,倒数 127 是 -128。因此,如果您想反转 Java 字节的位,您应该得到带有相反符号的字节并减去一个:

byte myByte = 123;
byte myInvertedByte = -myByte-1;
于 2012-01-26T15:14:42.087 回答
-1
private byte reverseBitsByte(byte x)
{
    int intSize = 8;

    byte y = 0;
    for (int position = intSize - 1; position >= 0; position--)
    {
        y += ((x & 1) << position);
        x >>= 1;
    }
    return y;
}
于 2014-07-08T17:53:32.583 回答