Reputation: 3172
This is so far what I've done to convert the 8 bytes I received to UInt64:
+ (UInt64)convertByteArrayToUInt64:(unsigned char *)bytes ofLength:(NSInteger)length
{
UInt64 data = 0;
for (int i = 0; i < length; i++)
{
data = data | ((UInt64) (bytes[i] & 0xff) << (24 - i * 8));
}
return data;
}
The sender that converts the data to 8 bytes data did it this way:
for(int i=1;i<9;i++)
{
statusdata[i] = (time >> 8*i & 0xff);
}
The 8 bytes data data that I received is:
01 00 00 00 00 00 00 3b
The output of my method is:
16777216
I tried to convert this "16777216" to bytes using calculator and I got:
01 00 00 00 00 00 00
which means the 3b was not included in conversion.
But, I tried this code under java and it's working fine. I don't know where the problem is.
Please help. Thanks in advance!
Upvotes: 1
Views: 1539
Reputation: 17724
A UInt64
is 8 bytes, so if you have an 8 byte buffer all you need to do is make a UInt64
pointer to it and dereference it (as long as the data is in little-endian format on x86 architectures, but I'll get to that in a sec),
So:
unsigned char foo[8] = {0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
UInt64 *n = (UInt64 *) foo; // pointer to value 0x0102030405060708
UInt64 nValue = *n;
Be aware though the individual byte values on x86 hardware are little-endian, so the least-significant byte goes first in the buffer. Thus if you think about the buffer above as individual base-16 digits, the number will be:
0x0102030405060708 (most significant byte is last in the buffer).
The trick you're looking for though is to simply cast your 8-byte buffer to a UInt64*
and dereference it. If you've never seen big-vs.-little endian storage/byte-order before I recommend you go read about it.
p.s. - The sender code is wrong btw, the array index (i
) needs to run from 0 to 7, so (i=0;i<8;++i)
, not 1-8 or the value of time
will not be copied correctly. Incidentally, the sender is attempting to copy time
into statusdata
in little-endian order (least-significant byte first in the buffer), but again, it's being done wrong.
Also, if the sender code is on Java you need to be careful that the value of time
isn't actually supposed to be negative. Java doesn't have unsigned integer values so if time
is negative and you reconstitute it to a UInt64 it will be a large positive value, which isn't what you'll want.
For the sake of completeness, I'll show you how to reconstitute the data byte-by-byte from the little-endian buffer, but remember, the sender code is wrong and needs to be rewritten to index from zero (and a typecast as shown above would get you there as well):
data = 0
for (i=0; i < 8; ++i) {
data = (data << 8) | bytes[i]; // bytes is already UInt8 * so no need to mask it
}
Upvotes: 4