反序列化函数(字节数组到uint32)

时间:2011-05-26 21:36:28

标签: c bytearray deserialization

编写反序列化函数以将字节数组转换为32位无符号整数的最佳方法是什么?

    typedef unsigned long  uint32;

    uint32 deserialize_uint32(unsigned char *buffer)
    {
        uint32 value = 0;

        value |= buffer[0] << 24;
        value |= buffer[1] << 16;
        value |= buffer[2] << 8;
        value |= buffer[3];
        return value;

    }

    unsigned char* deserialize_uint32B(unsigned char *buffer, uint32* value)
    {
        *value = 0;

        *value |= buffer[0] << 24;
        *value |= buffer[1] << 16;
        *value |= buffer[2] << 8;
        *value |= buffer[3];
        return buffer + 4;
    }

谢谢!或者如果有更好的方法请告诉我..谢谢!

4 个答案:

答案 0 :(得分:2)

我更喜欢你的第一个变体而不是第二个。或者,您可以通过使用四个局部变量来利用并行处理,这些变量将各个字节移位正确的量。然后,在最后一行中return b0shifted | b1shifted | b2shifted | b3shifted

无论如何,这完全取决于你的编译器。您的第二个变体包含更多的加载/存储操作,因此第一个变体具有较少的抽象操作。

关于可读性,可理解性和清晰度,您的第一个变体很棒。它也适用于您正在使用的任何奇怪的平台(endianess,alignment),前提是CHAR_BIT == 8

答案 1 :(得分:1)

人们可以明智地使用铸造来轻松完成这项工作。只需将char缓冲区转换为您想要的类型。

uint32 deserialize_uint32(unsigned char *buf)
{
    uint32 *x = (uint32*)buf;
    return *x;
}

unsigned char * deserialize_uint32B(unsigned char *buffer, uint32* value)
{
    *(uint32*)buffer = *value;
    return buffer;
}

答案 2 :(得分:0)

你可以写:

#include <arpa/inet.h>

uint32_t deserialize_uint32(unsigned char *buffer) {
    uint32_t res = *((uint32_t *) buffer);
    return ntohl(res);
}

unsigned char *serialize_uint32(unsigned char *buffer, uint32_t *value) {
    *((uint32_t *) buffer) = htonl(*value);
    return buffer;
}

此实现确保字节顺序与底层架构无关。

答案 3 :(得分:0)

您的第一个方法可能会产生更好的代码,因为在第二个方法中,编译器必须假设指针datavalue可以别名(尽管如果编译器能够内联,这可以减轻使用它的功能。)

如果您有C99编译器,您可能希望使用uint32_tinline和第二个版本restrict的优势。