简体   繁体   English

如何将UUID转换为大端?

[英]How to convert UUID to big endian?

My UUID is structured like this: 我的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];                   

};

I have functions that swap along 32 bit boundaries and a swap function that swaps along 16 bit boundaries. 我有功能swap沿32个边界和一个swap function沿16个边界交换。 I have tried calling swap32() on time_low and swap16() on time_mid and time_hi_and_version . 我已经打过电话swap32()time_lowswap16()time_midtime_hi_and_version I do not believe I need to swap bytes for the rest of the fields because two of them are 8 bit fields and I have read that the node part of a uuid does not change. 我不相信我需要为其余字段交换字节,因为其中两个是8位字段,我已经读过uuid的节点部分没有改变。 Here is a link for that reference. 这是该参考的链接。

The problem is when I complete the swaps the uuid that is printed does not match the one that was in little endian before being converted. 问题是当我完成交换时,打印的uuid与转换前的小端的uuid不匹配。

What is the correct way to convert a uuid following RFC-4122 standard from little endian to big endian . RFC-4122标准之后的uuid从little endianbig endian的正确方法是什么? And when converted should the uuids match? 当转换时,uuids应该匹配吗?

Re: 回覆:

Update: Starting uuid in little endian: 更新:以小端开始uuid:

 446831D3-FBA1-477B-BB07-CB067B00E86B 

Result from correctly swapping necessary fields: 正确交换必要字段的结果:

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

This looks horribly wrong. 这看起来非常错误。 We can deduce that if the swaps are correct and affect only the 32 and 16 bit fields, then without swapping the necessary fields, it would be this: 我们可以推断,如果交换是正确的并且仅影响32位和16位字段,那么在不交换必要字段的情况下,它将是:

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

What you seem to have have going on here is byte swapping within 64 bit units somewhere in your pipeline. 你在这里看到的是你的管道中某处64位单元内的字节交换。 Even the array of bytes is being reversed, suggesting that it might be loaded somewhere as part of a 64 bit load, which is subject to a swap64 operation. 甚至字节数组也被反转,这表明它可能作为64位加载的一部分加载到某处,这需要进行swap64操作。

Have you tried accessing the individual bytes? 您是否尝试过访问单个字节?

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;

Probably more efficient than calling a function. 可能比调用函数更有效。 :-) :-)

Note: the above method is platform independent. 注意:上述方法与平台无关。 Doesn't require any knowledge how the value is stored. 不需要知道value的存储方式。

Explanation: 说明:
Let packet be a buffer or memory destination for a uint32_t that needs to be stored into the buffer in Big Endian format (Most Significant Byte First). packetuint32_t的缓冲区或内存目的地,需要以Big Endian格式(最高有效字节优先)存储到缓冲区中。

The expression ( value >> 24 ) shifts the most significant byte to the least significant (byte) position. 表达式( value >> 24 )将最高有效字节移位到最低有效(字节)位置。 The expression "& 0xff" truncates, chops off, any extraneous values, resulting in an unsigned 8-bit value. 表达式“&0xff”截断,删除任何无关的值,从而产生无符号的8位值。 The value is then stored in the Most Significant position in the buffer at the first location. 然后将该值存储在第一个位置的缓冲区中的最高有效位置。

Likewise for the remaining bytes. 对于剩余的字节也是如此。

The recommended way is to use the function htonl ( htons for 16 bit integers) to convert from host byte order to network byte order, and ntohl ( ntohs for 16 bit integers) to convert from network byte order to host byte order 推荐的方法是使用函数htonl (16位整数的htons )从主机字节顺序转换为网络字节顺序,并使用ntohl (16位整数的ntohs )从网络字节顺序转换为主机字节顺序

Given the following structure: 鉴于以下结构:

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];                   
};

The code for serialization and deserialization might be as follows: 序列化和反序列化的代码可能如下:

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;
}

Note that you have to agree with the receiver/sender in the remote endpoint that you are both sending/receiving numbers in big endian. 请注意,您必须同意远程端点中的接收方/发送方您要以大端发送/接收数字。

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

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