views:

122

answers:

1

Hi,

Is there are a standard accepted way to byte-swap UUIDs for transmission over a network (or file storage)? (I want to send/store the 16 raw bytes rather than convert the UUID to a string representation.)

I thought at first I should partition the UUID into 4 32-bit integers and call htonl on each of them, but that didn't smell right. A UUID has internal structure (from RFC 4122):

typedef struct {
    unsigned32  time_low;
    unsigned16  time_mid;
    unsigned16  time_hi_and_version;
    unsigned8   clock_seq_hi_and_reserved;
    unsigned8   clock_seq_low;
    byte        node[6];
} uuid_t;

Would it be correct to do:

...
uuid.time_low = htonl( uuid.time_low );
uuid.time_mid = htons( uuid.time_mid );
uuid.time_hi_and_version = htons( uuid.time_high_and_version );
/* other fields are represented as bytes and shouldn't be swapped */
....

before writing, and then the correpsonding ntoh...calls after reading at the other end?

Thanks.

+2  A: 

Yes, that is the correct thing to do.

Each number (time_low, time_mid, time_hi_and_version) are subject to byte ordering. the node field is not. clock_seq_hi_and_reserved and clock_seq_low are also subject to byte ordering, but they are each one byte, so it doesn't matter.

Of course, it is up to you to make sure that you choose the right ordering on both ends, or understand what the ordering is on the other end if you don't control it. Microsoft of course uses little endian for their UUIDs. You can see Microsoft's definition of a UUID here.

Jared Oberhaus
Thanks. I'm controlling both ends. I'll choose host ordering internally, so if time_low is initialised to, say 0x01020304 on little-endian and sent over the network, the value will still be 0x01020304 on big-endian at the other end.
Steve Folly