到目前为止,我已经将我收到的8个字节转换为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;
}
将数据转换为8字节数据的发送方就是这样做的:
for(int i=1;i<9;i++)
{
statusdata[i] = (time >> 8*i & 0xff);
}
我收到的8字节数据是:
01 00 00 00 00 00 00 3b
我方法的输出是:
16777216
我尝试使用计算器将此“16777216”转换为字节,然后我得到了:
01 00 00 00 00 00 00
这意味着3b不包含在转换中。
但是,我在java下尝试了这个代码并且它工作正常。我不知道问题出在哪里。
请帮忙。提前谢谢!
答案 0 :(得分:3)
一个UInt64
是8个字节,所以如果你有一个8字节的缓冲区,你需要做的就是做一个UInt64
指针并取消引用它(只要数据很少 - x86体系结构上的endian格式,但我会在一秒内完成,
所以:
unsigned char foo[8] = {0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
UInt64 *n = (UInt64 *) foo; // pointer to value 0x0102030405060708
UInt64 nValue = *n;
请注意,虽然x86硬件上的单个字节值是little-endian,但最低有效字节在缓冲区中 first 。因此,如果您将上面的缓冲区视为单个基数为16的数字,则数字将为:
0x0102030405060708(最高有效字节在缓冲区中为最后一个字节。)
您正在寻找的技巧是简单地将8字节缓冲区转换为UInt64*
并取消引用它。如果您在推荐之前从未见过大小端存储/字节顺序,请阅读相关内容。
P.S。 - 发件人代码是错误的btw,数组索引(i
)需要从0运行到7,因此(i=0;i<8;++i)
,不 1-8或{{{{ 1}}将无法正确复制。顺便提一下,发件人 试图以小端顺序将time
复制到time
(缓冲区中的最低有效字节),但同样,它做错了。
此外,如果发件人代码在Java上,则需要注意statusdata
的值实际上不应该是负数。 Java没有无符号整数值,因此如果time
为负数并且您将其重新组合为UInt64,那么它将是一个很大的正值,这不是您想要的。
为了完整起见,我将向您展示如何从little-endian缓冲区逐字节重构数据,但请记住,发送方代码是错误的,需要重写为从零开始索引(和如上所示的类型转换也会让你在那里):
time