如何在 Java 中反转无符号字节的位?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3324707/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I invert bits of an unsigned byte in Java?
提问by DavidKelly999
I am trying to write a decoder for a very simple type of encryption. Numbers from 0-255 are entered via Scanner, the bits are inverted, and then converted to a character and printed.
我正在尝试为一种非常简单的加密类型编写解码器。0-255 之间的数字通过扫描仪输入,位被反转,然后转换为字符并打印。
For example, the number 178 should convert to the letter "M".
例如,数字 178 应转换为字母“M”。
178 is 10110010.
178 是 10110010。
Inverting all of the bits should give 01001101, which is 77 or "M" as a character.
反转所有位应给出 01001101,即 77 或“M”作为字符。
The main problem I have is that, as far as I can tell, Java does not support unsigned bytes. I could read values as an int or a short, but then the values will be off during the conversion due to the extra bits. Ideally I could just use the bitwise complement operator, but I think I will end up getting negative values if I do this with signed numbers. Any ideas on how I should approach this?
我遇到的主要问题是,据我所知,Java 不支持无符号字节。我可以将值读取为 int 或 short,但是由于额外的位,这些值将在转换过程中关闭。理想情况下,我可以只使用按位补码运算符,但我认为如果我使用有符号数执行此操作,我最终会得到负值。关于我应该如何解决这个问题的任何想法?
回答by Nick Fortescue
The easiest way to do this is three stages:
最简单的方法是三个阶段:
- Read the value as an int (32 bits in java). It may read as negative but we only care about the bottom 8 bits anyway.
int i = scanner.nextByte();
- Do the inversion as an int using bitwise operators (as you say will give you 1s as high order bits:
i = ~i;
- Lose the high order bits with a logical AND:
i = i & 0xFF;
- 将值读取为 int(Java 中的 32 位)。它可能读为负数,但无论如何我们只关心底部的 8 位。
int i = scanner.nextByte();
- 使用按位运算符将反转作为 int 进行(如您所说,会给您 1 作为高位:
i = ~i;
- 使用逻辑 AND 丢失高位:
i = i & 0xFF;
Then just use the result as a character (which is actually 16 bits in java, but we will only use 8 of them):
然后只需将结果用作字符(在java中实际上是16位,但我们只会使用其中的8位):
char c=(char)a;
System.out.println(c);
All together:
全部一起:
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);
回答by Merlyn Morgan-Graham
If Java supports this, you could read it into a larger type, bitwise-compliment, then bit-mask out the unwanted bits.
如果 Java 支持这一点,您可以将其读入更大的类型,按位赞美,然后位屏蔽掉不需要的位。
int x = [your byte];
x = ~x & 0xFF;
回答by Mark Byers
Bitwise operations in Java are defined for int
so it makes sense to work with int
rather than byte
. You can use Scanner.nextInt
, rather than Scanner.nextByte
. You should validate the user's input to ensure that all integers entered are in the range 0 to 255 and display an appropriate error message if an out-of-range number is encountered.
Java 中的按位运算是为 for 定义的,int
因此使用int
而不是byte
. 您可以使用Scanner.nextInt
, 而不是Scanner.nextByte
。您应该验证用户的输入以确保输入的所有整数都在 0 到 255 的范围内,并在遇到超出范围的数字时显示相应的错误消息。
Once you have the number stored in an integer then to flip the least significant 8 bits you can XOR with 0xff. This should work as you expect for all inputs between 0 and 255:
一旦您将数字存储在整数中,然后翻转最低有效 8 位,您就可以与 0xff 进行异或。对于 0 到 255 之间的所有输入,这应该可以正常工作:
x ^= 0xff;
Example:
例子:
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);
}
}
Result:
结果:
77
255
0
回答by starblue
~n & 0xff
~
does the complement and implicitly converts to an integer like all numeric operations do, then & 0xff
masks out everything except the lower 8 bits to get the unsigned value, again as an integer.
~
进行补码并像所有数字运算一样隐式转换为整数,然后& 0xff
屏蔽除低 8 位之外的所有内容以获得无符号值,再次作为整数。
I first read your question differently, to invert the order instead of the values of the bits, and this was the answer.
我首先以不同的方式阅读您的问题,以反转顺序而不是位的值,这就是答案。
You can use Integer.reverse()
(untested):
您可以使用Integer.reverse()
(未经测试):
Integer.reverse(n << 24) & 0xff
回答by stacker
I would simply use the ones complement and get rid of the other bits by using binary and.
我会简单地使用那些补码并通过使用二进制和来摆脱其他位。
public class Conv {
public static void main(String[] args) {
int val = 178;
val = ~val & 0xff;
System.out.println((char) val);
}
}
回答by Vlad
Here are Java bytes, sorted by binary representation (from 00000000 to 11111111):
以下是 Java 字节,按二进制表示排序(从 00000000 到 11111111):
0, 1, 2, .., 126, 127, -128, -127, .., -2, -1
0, 1, 2, .., 126, 127, -128, -127, .., -2, -1
00000000 is 0, 11111111 is -1
00000000 是 0,11111111 是 -1
Inverted 0 is -1, inverted 1 is -2, ..., inverted 127 is -128. Thus if you want to invert bits of Java byte you should get your byte with opposite sign and subtract one:
倒 0 是 -1,倒 1 是 -2,...,倒 127 是 -128。因此,如果您想反转 Java 字节的位,您应该得到具有相反符号的字节并减去一:
byte myByte = 123;
byte myInvertedByte = -myByte-1;
回答by Xkynar
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;
}