UUID generation using native platform libraries (Windows / Linux)

Apr 12, 2024    #c   #c++  

UUID

This post explains how to use native platform libraries to produce Universally Unique Identifiers on Windows and Linux.

Wikipedia describes a UUID like so:

When generated according to the standard methods, UUIDs are, for practical purposes, unique. Their uniqueness does not depend on a central registration authority or coordination between the parties generating them, unlike most other numbering schemes. While the probability that a UUID will be duplicated is not zero, it is generally considered close enough to zero to be negligible.

The standard UUID is a 128 bit or 16 bytes long.

Windows

UUID generation on Windows is provided by the Rpcrt library. The corresponding header file containing the interface is Rpc.h, where as Rpcrt4.lib and Rpcrt4.dll contain the implementaion. The following program produces a UUID, parses it to a c-string, and prints the parsed value to the terminal:

#include <Rpc.h>
#include <iostream>

int main()
{
    UUID uuid;
    UuidCreate(&uuid);

    RPC_CSTR buffer = NULL;
    UuidToStringA(&uuid, &buffer);
    std::cout << (char*)buffer;
    RpcStringFree(&buffer);
}

Notice the cast from char* to RPC_CSTR* in the above code. Windows C libraries have a weird relationship strings. It’s honestly all over the place and a whole set of macros are provided to deal with them. I guess RPC_CSTR is the string type in the Rpc library. There was probably a good reason to do this back in day, but who knows what that reason is in 2024 — probably not even Microsoft.

Compiling the above program is done like so:

cl main.cpp /link Rpcrt4.lib

Output:

c2345d15-e082-4efa-bc58-aab5d4512f8c

If you get the error 'cl' is not recognized as an internal or external command., you can refer to this post which describes how to set up a cli-based development environment.

Linux

UUID generation on Linux is a bit more straightforward than on Windows since there is no need to do any weird pointer casts, but you probably need to install the actual libraries despite them being developed by the Linux kernel team:

The library is simply called libuuid, and you can acquire it using your package manager of choice, probably using something like:

sudo apt install libuuid-dev

The following program does exactly as its Windows counterpart, but meant to be executed on Linux:

#include <uuid/uuid.h>
#include <iostream>

int main()
{
    uuid_t uuid;            // This is a #typedef to unsigned char[16]
    uuid_generate(uuid);
    
    char buffer[64];
    uuid_unparse(uuid, buffer);

    std::cout << buffer;

    return 0;
}

Compiling the above program on Linux is done like so:

g++ main.cpp -luuid

Output:

4aa14188-be77-4dcc-9bea-a55ab4790e93

If you are interested, you can inspect each char in the UUID string:

for (char* ptr = &buffer[0]; *ptr != '\0'; i++)
    std::cout << ptr - &buffer[0] << ": " << *ptr << '\n';

Output:

d93c3a0e-68e5-4a54-87d1-c3ace340ab21
0: d
1: 9
2: 3
3: c
4: 3
5: a
6: 0
7: e
8: -
9: 6
10: 8
11: e
12: 5
13: -
14: 4
15: a
16: 5
17: 4
18: -
19: 8
20: 7
21: d
22: 1
23: -
24: c
25: 3
26: a
27: c
28: e
29: 3
30: 4
31: 0
32: a
33: b
34: 2
35: 1

Resources