0

Update!!! I'm trying to reverse an bitwise Left-Shift. I have code:

int n1;
int n2;
int n3;
n1 = n1 + 128;
n2 = n2 + 128;
n3 = n3 + 128;
int size = n1 + ((n3 << 8) + n2 << 8); // size = 9999

How could I get back n1,n2,n3 to given the result 9999?

pmt9
  • 51
  • 1
  • 6
  • 2
    This code doesn't pass compilation, so it doesn't do anything. – Eran Jul 15 '20 at 11:48
  • 1
    there seems to be an open paren `(` missing somewhere – Joni Jul 15 '20 at 11:49
  • 2
    @Joni that's one error. Another error is the attempt to assign a byte array to an int variable. – Eran Jul 15 '20 at 11:50
  • 2
    In any case, does this answer your question?https://stackoverflow.com/questions/141525/what-are-bitwise-shift-bit-shift-operators-and-how-do-they-work – Joni Jul 15 '20 at 11:50
  • 2
    This is decompiled code, right? I really hope people aren't writing such awful code for real. – Andy Turner Jul 15 '20 at 12:09
  • 1
    *For [revision 3](https://stackoverflow.com/revisions/62914101/3) of the question:* Unless the `dataInputStream` starts with 3 bytes having value `0x80` (aka `-128`, making `n1 = 0`), the **loop will execute forever**, since the values of `n1`, `n3`, and `n4` never changes in the loop. Well actually, the loop will run **until `read(...)` throws `EOFException`**. – Andreas Jul 15 '20 at 12:09

2 Answers2

2

Offsetting by 128 is sometimes used in Java to work around byte being signed. Adding 128 ensures that the result (which will be an int) is non-negative again. As long as it is symmetric with the encoder (the corresponding writeMessage), then it is a way to encode unsigned bytes.

After that, the bytes are reassembled into something bigger. That would not work right with signed bytes. By the way I think a pair of parentheses is missing, and the expression should be n1 + ((n3 << 8) + n2 << 8), or clearer: n1 + (n2 << 8) + (n3 << 16)

An alternative is using byteValue & 0xFF to get rid of the leading ones added by sign-extension. That has the benefit that the raw bytes are used "as themselves", without a strange offset.


The inverse is extracting the bytes and offsetting them by 128 again (adding or subtracting 128 would actually do the same thing, but for symmetry it makes more sense to subtract here), for example:

byte n1 = (byte)((size & 0xFF) - 128);
byte n2 = (byte)((size >> 8 & 0xFF) - 128);
byte n3 = (byte)((size >> 16 & 0xFF) - 128);

The & 0xFF operation is not strictly necessary (the final cast to byte gets rid of the high bits), but makes it clear that bytes are being extracted.

harold
  • 61,398
  • 6
  • 86
  • 164
1

It's called bit shifting. It's shifting the bits (at the binary level) to the right by 8.

128 << 8 = 32768

Say you have 16, 10000 in binary and shift it left by 2; 16 << 2 = 64 (1000000 binary)

This is common for encryption, data compression, or even dealing with something as simple as color values (when you want separate RGB components of a color represented as a single integer)

In your example, it sounds like multiple values were combined into a single integer to conserve space when sending a packet. Bit shifting is a way or extracting those individual values from a larger number. But that's just a guess.

Phaelax z
  • 1,814
  • 1
  • 7
  • 19