Method 1: Boost.UUID (Recommended)
Boost.UUID is the most portable and feature-rich C++ UUID library:
C++ - Boost.UUID
#include
#include
#include
#include
int main() {
// Random UUID v4 generator
boost::uuids::random_generator gen;
boost::uuids::uuid id = gen();
// Print UUID
std::cout << id << std::endl;
// Output: 550e8400-e29b-41d4-a716-446655440000
// Convert to string
std::string uuid_str = boost::uuids::to_string(id);
std::cout << "UUID string: " << uuid_str << std::endl;
// Generate name-based UUID v5 (SHA-1)
boost::uuids::name_generator_sha1 name_gen(boost::uuids::ns::dns());
boost::uuids::uuid dns_uuid = name_gen("example.com");
std::cout << "DNS UUID: " << dns_uuid << std::endl;
// Nil UUID (all zeros)
boost::uuids::uuid nil = boost::uuids::nil_uuid();
std::cout << "Nil UUID: " << nil << std::endl;
// Check if nil
if (nil.is_nil()) {
std::cout << "UUID is nil" << std::endl;
}
return 0;
}
Installation:
# Ubuntu/Debian
sudo apt install libboost-all-dev
# macOS
brew install boost
# Windows (vcpkg)
vcpkg install boost-uuid
Boost.UUID String Parsing
C++
#include
#include
#include
#include
int main() {
// Parse from string
boost::uuids::string_generator str_gen;
try {
boost::uuids::uuid id = str_gen("550e8400-e29b-41d4-a716-446655440000");
std::cout << "Parsed UUID: " << id << std::endl;
// Also accepts uppercase and no hyphens
boost::uuids::uuid id2 = str_gen("550E8400E29B41D4A716446655440000");
std::cout << "Parsed UUID2: " << id2 << std::endl;
} catch (const std::exception& e) {
std::cerr << "Parse error: " << e.what() << std::endl;
}
// Compare UUIDs
boost::uuids::uuid uuid1 = str_gen("550e8400-e29b-41d4-a716-446655440000");
boost::uuids::uuid uuid2 = str_gen("6ba7b810-9dad-11d1-80b4-00c04fd430c8");
if (uuid1 == uuid2) {
std::cout << "UUIDs are equal" << std::endl;
} else {
std::cout << "UUIDs are different" << std::endl;
}
return 0;
}
Method 2: Windows API (Windows Only)
Use Windows CoCreateGuid for native Windows UUID generation:
C++ - Windows API
#include
#include
#include
#pragma comment(lib, "rpcrt4.lib")
int main() {
UUID uuid;
// Generate GUID
HRESULT hr = CoCreateGuid(&uuid);
if (FAILED(hr)) {
std::cerr << "Failed to create GUID" << std::endl;
return 1;
}
// Convert to string
RPC_CSTR szUuid = nullptr;
if (UuidToStringA(&uuid, &szUuid) == RPC_S_OK) {
std::cout << "UUID: " << (char*)szUuid << std::endl;
RpcStringFreeA(&szUuid);
}
// Alternative: CoCreateGuid
GUID guid;
CoCreateGuid(&guid);
// Format as string manually
char buffer[64];
snprintf(buffer, sizeof(buffer),
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
std::cout << "GUID: " << buffer << std::endl;
return 0;
}
Method 3: Linux libuuid (Linux Only)
Native Linux UUID generation using libuuid:
C++ - libuuid
#include
#include
#include
// Compile: g++ -o prog prog.cpp -luuid
int main() {
uuid_t uuid;
char uuid_str[37];
// Generate random UUID
uuid_generate_random(uuid);
// Convert to string
uuid_unparse_lower(uuid, uuid_str);
std::cout << "UUID: " << uuid_str << std::endl;
// Uppercase
uuid_unparse_upper(uuid, uuid_str);
std::cout << "UUID (upper): " << uuid_str << std::endl;
// Time-based UUID v1
uuid_t uuid_time;
uuid_generate_time(uuid_time);
uuid_unparse(uuid_time, uuid_str);
std::cout << "UUID v1: " << uuid_str << std::endl;
// Parse UUID from string
uuid_t parsed_uuid;
if (uuid_parse("550e8400-e29b-41d4-a716-446655440000", parsed_uuid) == 0) {
std::cout << "Successfully parsed UUID" << std::endl;
}
// Compare UUIDs
if (uuid_compare(uuid, uuid_time) != 0) {
std::cout << "UUIDs are different" << std::endl;
}
return 0;
}
Installation: sudo apt install uuid-dev (Ubuntu/Debian)
Method 4: Pure C++17 (No Dependencies)
Generate UUID v4 using only standard C++17:
C++17
#include
#include
#include
#include
std::string generate_uuid_v4() {
static std::random_device rd;
static std::mt19937 gen(rd());
static std::uniform_int_distribution<> dis(0, 15);
static std::uniform_int_distribution<> dis2(8, 11);
std::stringstream ss;
ss << std::hex << std::setfill('0');
// Generate 8-4-4-4-12 format
for (int i = 0; i < 8; i++) {
ss << dis(gen);
}
ss << "-";
for (int i = 0; i < 4; i++) {
ss << dis(gen);
}
ss << "-";
// Version 4
ss << "4";
for (int i = 0; i < 3; i++) {
ss << dis(gen);
}
ss << "-";
// Variant (8, 9, a, or b)
ss << dis2(gen);
for (int i = 0; i < 3; i++) {
ss << dis(gen);
}
ss << "-";
for (int i = 0; i < 12; i++) {
ss << dis(gen);
}
return ss.str();
}
int main() {
std::cout << "UUID: " << generate_uuid_v4() << std::endl;
// Generate multiple
for (int i = 0; i < 5; i++) {
std::cout << generate_uuid_v4() << std::endl;
}
return 0;
}
UUID Class Wrapper
Create a reusable UUID class for modern C++:
C++ Class
#include
#include
#include
#include
#include
class UUID {
private:
std::array data;
public:
UUID() {
generate();
}
void generate() {
static std::random_device rd;
static std::mt19937 gen(rd());
static std::uniform_int_distribution<> dis(0, 255);
for (auto& byte : data) {
byte = static_cast(dis(gen));
}
// Set version to 4
data[6] = (data[6] & 0x0F) | 0x40;
// Set variant to RFC4122
data[8] = (data[8] & 0x3F) | 0x80;
}
std::string to_string() const {
std::stringstream ss;
ss << std::hex << std::setfill('0');
for (size_t i = 0; i < 16; i++) {
ss << std::setw(2) << static_cast(data[i]);
if (i == 3 || i == 5 || i == 7 || i == 9) {
ss << "-";
}
}
return ss.str();
}
static UUID from_string(const std::string& str) {
UUID uuid;
std::string hex_str = str;
// Remove hyphens
hex_str.erase(
std::remove(hex_str.begin(), hex_str.end(), '-'),
hex_str.end()
);
if (hex_str.length() != 32) {
throw std::invalid_argument("Invalid UUID string");
}
for (size_t i = 0; i < 16; i++) {
uuid.data[i] = std::stoi(
hex_str.substr(i * 2, 2),
nullptr,
16
);
}
return uuid;
}
bool operator==(const UUID& other) const {
return data == other.data;
}
bool operator!=(const UUID& other) const {
return !(*this == other);
}
};
// Usage
int main() {
UUID uuid;
std::cout << "Generated: " << uuid.to_string() << std::endl;
// Parse from string
UUID parsed = UUID::from_string("550e8400-e29b-41d4-a716-446655440000");
std::cout << "Parsed: " << parsed.to_string() << std::endl;
// Compare
if (uuid != parsed) {
std::cout << "UUIDs are different" << std::endl;
}
return 0;
}
Cross-Platform UUID Generator
Detect platform and use the best available method:
Cross-Platform C++
#include
#ifdef _WIN32
#include
#include
#pragma comment(lib, "rpcrt4.lib")
#elif defined(__linux__)
#include
#else
#include
#include
#include
#endif
std::string generate_uuid() {
#ifdef _WIN32
UUID uuid;
UuidCreate(&uuid);
RPC_CSTR szUuid = nullptr;
std::string result;
if (UuidToStringA(&uuid, &szUuid) == RPC_S_OK) {
result = reinterpret_cast(szUuid);
RpcStringFreeA(&szUuid);
}
return result;
#elif defined(__linux__)
uuid_t uuid;
char uuid_str[37];
uuid_generate_random(uuid);
uuid_unparse_lower(uuid, uuid_str);
return std::string(uuid_str);
#else
// Fallback: Pure C++ implementation
static std::random_device rd;
static std::mt19937 gen(rd());
static std::uniform_int_distribution<> dis(0, 15);
static std::uniform_int_distribution<> dis2(8, 11);
std::stringstream ss;
ss << std::hex;
for (int i = 0; i < 8; i++) ss << dis(gen);
ss << "-";
for (int i = 0; i < 4; i++) ss << dis(gen);
ss << "-4";
for (int i = 0; i < 3; i++) ss << dis(gen);
ss << "-" << dis2(gen);
for (int i = 0; i < 3; i++) ss << dis(gen);
ss << "-";
for (int i = 0; i < 12; i++) ss << dis(gen);
return ss.str();
#endif
}
int main() {
std::cout << "UUID: " << generate_uuid() << std::endl;
return 0;
}