Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I invert bits of an unsigned byte in Java?

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.

For example, the number 178 should convert to the letter "M".

178 is 10110010.

Inverting all of the bits should give 01001101, which is 77 or "M" as a character.

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?

like image 803
DavidKelly999 Avatar asked Jul 24 '10 10:07

DavidKelly999


People also ask

How do you invert a byte?

I found the way to invert a complete byte and is by using " ~ " instead of " ! ".

How do you flip a bit in Java?

Java BitSet flip() methodThe flip() method of Java BitSet class sets the bit set to its complement. For example, if a bit value contains a true value then if you apply flip() operation on it, it will return false. There are two overloaded flip() method available in BitSet class.

Does Java have unsigned byte?

Java doesn't have unsigned bytes (0 to 255). To make an unsigned byte, we can cast the byte into an int and mask (bitwise and) the new int with a 0xff to get the last 8 bits or prevent sign extension.

What is 0xff?

0xff is a number represented in the hexadecimal numeral system (base 16). It's composed of two F numbers in hex. As we know, F in hex is equivalent to 1111 in the binary numeral system. So, 0xff in binary is 11111111.


4 Answers

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);
    }
}
like image 193
stacker Avatar answered Oct 21 '22 21:10

stacker


~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.

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(n << 24) & 0xff
like image 39
starblue Avatar answered Oct 21 '22 22:10

starblue


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.

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:

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
like image 39
Mark Byers Avatar answered Oct 21 '22 23:10

Mark Byers


If Java supports this, you could read it into a larger type, bitwise-compliment, then bit-mask out the unwanted bits.

int x = [your byte];
x = ~x & 0xFF;
like image 2
Merlyn Morgan-Graham Avatar answered Oct 21 '22 21:10

Merlyn Morgan-Graham