I receive a datapacket containing a byte array and I have to get some integer values from it. Here is a part of the documentation. Can someone help me please?
This comes
First, I'd convert this to an integer:
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
int timestamp = ByteBuffer.wrap(byte_array).order(ByteOrder.LITTLE_ENDIAN).getInt();
Next, I'd take it apart:
int yearCode = (timestamp >> 26) & 0b111111;
int monthCode = (timestamp >> 22) & 0b1111;
int dayCode = (timestamp >> 17) & 0b11111;
int hourCode = (timestamp >> 12) & 0b11111;
int minCode = (timestamp >> 6) & 0b111111;
int secCode = (timestamp >> 0) & 0b111111;
The masking in the first line and shifting in the last line are not strictly necessary, but are left in for clarity.
The final step is to add 1900 to the yearCode
and you're done!
What you need is some bitwise operations. First, construct an int out of the bytes:
int n = b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
Then, chop up the int into components. Now, your question does not specify which way do the fields go, right-to-left or left-to-right. That question is related to endianness, but not identical. So let's assume that the fields go from left to right.
Good sense suggests left-to-right. This way the integer representations of time values can be compared - the significance of year bits is more than month bits etc, so when you compare integers that correspond to two moments in time, you get a chronologically correct result.
Here's a mental image for you. This is an integer variable, composed of bits:
f e d c b a 9 8 7 6 5 4 3 2 1 0
-----
offset is 6, length is 3
Let's define a function that takes a arbitrary chunk from an int at a given offset (in bits), with a given length (in bits).
int bits(int n, int offset, int length)
{
//shift the bits rightward, so that the desired chunk is at the right end
n = n >> (31 - offset - length);
//prepare a mask where only the rightmost `length` bits are 1's
int mask = ~(-1 << length);
//zero out all bits but the right chunk
return n & mask;
}
Could've been a one-liner, but I wanted to make it somewhat instructive. Folks in the answers below effectively inline this function, by specifying the shift factor and the mask by hand for each chunk.
Now let's decompose. Assuming n comes from the topmost snippet:
int year = bits(n, 0, 6),
month = bits(n, 6, 4),
day = bits(n, 10, 5),
hour = bits(n, 15, 5),
min = bits(n, 20, 6),
sec = bits(n, 26, 6);
We get the values of the offset by combining the total lengths of the previous fields together. This is under the assumption that the fields go left to right; if they go the other way around, the offset values would be different.
Did that make sense?
EDIT: if the bit chunks go right to leftt, then here's how it'd go:
int sec = bits(n, 0, 6),
min = bits(n, 6, 6),
hour = bits(n, 12, 5),
day = bits(n, 17, 5),
month = bits(n, 22, 4),
year = bits(n, 26, 6);
Assuming you have java 7, you should be able to read the year as
int year = 1990
+ ((b[0] & 0b1000_0000) << 5)
+ ((b[0] & 0b0100_0000) << 4)
+ ((b[0] & 0b0010_0000) << 3)
+ ((b[0] & 0b0001_0000) << 2)
+ ((b[0] & 0b0000_1000) << 1)
+ ((b[0] & 0b0000_0100));
and the month as
int month = 1
+ ((b[0] & 0b1000_0010) << 3)
+ ((b[0] & 0b0100_0001) << 2)
+ ((b[1] & 0b1000_0000) << 1)
+ ((b[1] & 0b0100_0000));
I let you do the others ints in the same way.
I don't have java7 and can't test now, I hope I'm not wrong. It's also possible that the order of the bytes is the reverse one.