Objective-C 如何将字节数组转换为 UInt64

How Convert Byte Array To UInt64 In Objective-C

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

请帮忙。提前致谢!

A UInt64 是 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 字节缓冲区转换为 UInt64* 并取消引用它。如果你在我推荐你去阅读它之前从未见过 big-vs.-little endian storage/byte-order。

p.s。 - 顺便说一句,发件人代码错误,数组索引 (i) 需要 运行 从 0 到 7,所以 (i=0;i<8;++i) 不是 1- 8 或 time 的值将无法正确复制。顺便说一句,发送者 试图以小端顺序(缓冲区中的最低有效字节在前)将 time 复制到 statusdata 中,但同样,它正在做错了。

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

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

data = 0

for (i=0; i < 8; ++i) {
    data = (data << 8) | bytes[i];  // bytes is already UInt8 * so no need to mask it
}