繁体   English   中英

如何将UUID转换为大端?

[英]How to convert UUID to big endian?

我的UUID结构如下:

struct UUID_FIELDS
{
    uint32_t time_low;                
    uint16_t time_mid;                 
    uint16_t time_hi_and_version;      
    uint8_t clock_seq_hi_and_reserved;
    uint8_t clock_seq_low;             
    uint8_t node[6];                   

};

我有功能swap沿32个边界和一个swap function沿16个边界交换。 我已经打过电话swap32()time_lowswap16()time_midtime_hi_and_version 我不相信我需要为其余字段交换字节,因为其中两个是8位字段,我已经读过uuid的节点部分没有改变。 这是该参考的链接。

问题是当我完成交换时,打印的uuid与转换前的小端的uuid不匹配。

RFC-4122标准之后的uuid从little endianbig endian的正确方法是什么? 当转换时,uuids应该匹配吗?

回覆:

更新:以小端开始uuid:

 446831D3-FBA1-477B-BB07-CB067B00E86B 

正确交换必要字段的结果:

 FBA1477B-31D3-4468-6BE8-007B06CB07BB 

这看起来非常错误。 我们可以推断,如果交换是正确的并且仅影响32位和16位字段,那么在不交换必要字段的情况下,它将是:

Original: 446831D3-FBA1-477B-BB07-CB067B00E86B
           |       _______/   |       _______/
            \____ /_______     \____ /______
            _____/        \    _____/       \
           /               |  /              |
Received: 7B47A1FB-D331-6844-6BE8-007B06CB07BB   # "de-swapped".

你在这里看到的是你的管道中某处64位单元内的字节交换。 甚至字节数组也被反转,这表明它可能作为64位加载的一部分加载到某处,这需要进行swap64操作。

您是否尝试过访问单个字节?

uint8_t packet[4];
uint32_t value;
packet[0] = (value >> 24) & 0xFF;
packet[1] = (value >> 16) & 0xFF;
packet[2] = (value >>  8) & 0xFF;
packet[3] = value & 0xFF;

可能比调用函数更有效。 :-)

注意:上述方法与平台无关。 不需要知道value的存储方式。

说明:
packetuint32_t的缓冲区或内存目的地,需要以Big Endian格式(最高有效字节优先)存储到缓冲区中。

表达式( value >> 24 )将最高有效字节移位到最低有效(字节)位置。 表达式“&0xff”截断,删除任何无关的值,从而产生无符号的8位值。 然后将该值存储在第一个位置的缓冲区中的最高有效位置。

对于剩余的字节也是如此。

推荐的方法是使用函数htonl (16位整数的htons )从主机字节顺序转换为网络字节顺序,并使用ntohl (16位整数的ntohs )从网络字节顺序转换为主机字节顺序

鉴于以下结构:

struct UUID_FIELDS
{
    uint32_t time_low;                
    uint16_t time_mid;                 
    uint16_t time_hi_and_version;      
    uint8_t clock_seq_hi_and_reserved;
    uint8_t clock_seq_low;             
    uint8_t node[6];                   
};

序列化和反序列化的代码可能如下:

std::string serialize(UUID_FIELDS fields) {
    std::string buffer(sizeof(fields), '\0');

    // convert all fields with size > 1 byte to big endian (network byte order)
    fields.time_low = htonl(fields.time_low);
    fields.time_mid = htons(fields.time_mid);
    fields.time_hi_and_version = htons(fields.time_hi_and_version);

    memcpy(&buffer[0], &fields, sizeof(fields));

    return buffer;
}

UUID_FIELDS deserialize(const std::string& buffer) {
    UUID_FIELDS fields;

    assert(buffer.size() == sizeof(fields));

    memcpy(&fields, &buffer[0], sizeof(fields));

    // convert all fields with size > 1 byte to little endian (maybe) (host byte order)
    fields.time_low = ntohl(fields.time_low);
    fields.time_mid = ntohs(fields.time_mid);
    fields.time_hi_and_version = ntohs(fields.time_hi_and_version);

    return fields;
}

请注意,您必须同意远程端点中的接收方/发送方您要以大端发送/接收数字。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM