1

到目前为止,这是我将收到的 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下尝试了这段代码,它工作正常。我不知道问题出在哪里。

请帮忙。提前致谢!

4

1 回答 1

4

AUInt64是 8 个字节,所以如果你有一个 8 字节的缓冲区,你需要做的就是创建一个UInt64指向它的指针并取消引用它(只要数据在 x86 架构上是 little-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 硬件上的各个字节值是小端序的,但最不重要的字节首先进入缓冲区。因此,如果您将上面的缓冲区视为单独的 base-16 数字,则该数字将是:

0x0102030405060708(最高有效字节在缓冲区的最后一个)。

不过,您正在寻找的技巧是将您的 8 字节缓冲区简单地转换为 aUInt64*并取消引用它。如果您在我建议您阅读之前从未见过大端与小端存储/字节顺序。

ps - 顺便说一句,发送者代码错误,数组索引 ( i) 需要从 0 到 7 运行,因此(i=0;i<8;++i)不是1-8,否则time将无法正确复制 的值。顺便说一句,发送方试图以 little-endian 顺序(缓冲区中的最低有效字节在前)复制timestatusdata但同样,它做错了。

此外,如果发件人代码在 Java 上,您需要注意 的值time实际上不应该是负数。Java 没有无符号整数值,因此如果time它是负数并且您将其重构为 UInt64,它将是一个很大的正值,这不是您想要的。

为了完整起见,我将向您展示如何从 little-endian 缓冲区中逐字节重构数据,但请记住,发送方代码是错误的,需要重写为从零开始索引(并且类型转换为上面显示的也会让你到达那里):

data = 0

for (i=0; i < 8; ++i) {
    data = (data << 8) | bytes[i];  // bytes is already UInt8 * so no need to mask it
}
于 2015-09-16T03:59:59.043 回答