簡體   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