Skip to main content

Searching...

Tools
Articles
View All Results

Developer Lab · C++

Generate UUID in C++

C++ has no standard UUID type yet (C++23). Use stduuid (header-only, C++17) or Boost.Uuid - both use std::random_device for OS CSPRNG entropy and generate ~10-50M UUIDs/sec.

Quick Reference

Library Type C++ Standard Use Case
stduuid Header-only C++17 Lightweight, no build system changes
Boost.Uuid Header-only C++11 Already using Boost, more features
Windows CoCreateGuid Win32 API Any COM/DCOM GUIDs on Windows

Primary Implementation

Production Ready
cpp
// stduuid - header-only, C++17
// https://github.com/mariusbancila/stduuid
#include <uuid.h>
#include <iostream>
#include <string>

int main() {
    // System generator uses std::random_device → OS CSPRNG
    uuids::uuid_system_generator gen;

    // Generate a UUID v4
    auto id = gen();
    std::cout << uuids::to_string(id) << "\n";
    // → f47ac10b-58cc-4372-a567-0e02b2c3d479

    // As a string
    std::string id_str = uuids::to_string(id);

    // Parse and validate
    auto parsed = uuids::uuid::from_string("f47ac10b-58cc-4372-a567-0e02b2c3d479");
    if (parsed.has_value()) {
        std::cout << "Valid UUID\n";
    }

    // Check if nil (all zeros)
    if (id.is_nil()) {
        std::cout << "UUID is nil\n";
    }

    // Generate multiple
    std::vector<uuids::uuid> ids;
    for (int i = 0; i < 5; ++i) {
        ids.push_back(gen());
    }
    return 0;
}

All UUID Versions

stduuid - UUID v4 (header-only, C++17)

cpp
#include <uuid.h>

// uuid_system_generator uses std::random_device → OS CSPRNG
uuids::uuid_system_generator gen;
auto id = gen();
std::string id_str = uuids::to_string(id);
// → "550e8400-e29b-41d4-a716-446655440000"

Boost.Uuid - UUID v4

cpp
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <sstream>

boost::uuids::random_generator gen;
boost::uuids::uuid id = gen();

// Convert to string
std::ostringstream oss;
oss << id;
std::string id_str = oss.str();
// → "550e8400-e29b-41d4-a716-446655440000"

// Or use boost::uuids::to_string
std::string id_str2 = boost::uuids::to_string(id);

Windows - CoCreateGuid (COM/DCOM)

cpp
#include <objbase.h>
#include <string>

GUID guid;
CoCreateGuid(&guid);

// Format as string
wchar_t buf[40];
StringFromGUID2(guid, buf, 40);
// → L"{F47AC10B-58CC-4372-A567-0E02B2C3D479}"

Real-World Use Cases

1. Game engine entity IDs

cpp
#include <uuid.h>
#include <unordered_map>

// Create a generator once - reuse it
static uuids::uuid_system_generator uuid_gen;

struct Entity {
    uuids::uuid id;
    std::string name;
    float x, y, z;

    Entity(std::string name, float x, float y, float z)
        : id(uuid_gen()), name(std::move(name)), x(x), y(y), z(z) {}
};

// Fast lookup by UUID
std::unordered_map<uuids::uuid, Entity> entity_registry;

2. Embedded system - unique device ID

cpp
#include <uuid.h>
#include <fstream>

// Generate a device UUID once and persist it
std::string get_or_create_device_id(const std::string& path) {
    std::ifstream in(path);
    if (in.good()) {
        std::string id;
        std::getline(in, id);
        return id;
    }
    uuids::uuid_system_generator gen;
    std::string id = uuids::to_string(gen());
    std::ofstream out(path);
    out << id;
    return id;
}

3. Boost.Uuid - name-based UUID v5

cpp
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>

// SHA-1 hash of namespace + name - deterministic
boost::uuids::name_generator_sha1 gen(boost::uuids::ns::dns());
boost::uuids::uuid id = gen("example.com");
std::cout << boost::uuids::to_string(id) << "\n";
// → always "cfbff0d1-9375-5685-968c-48ce8b15ae17"

Common Mistakes

Using rand() for UUID generation

rand() is not CSPRNG-backed and only provides 15–31 bits of entropy. Always use std::random_device (via stduuid or Boost) which maps to the OS CSPRNG.

Creating a new generator on every call

Constructing uuids::uuid_system_generator or boost::uuids::random_generator on every UUID generation is expensive - it re-seeds from the OS entropy pool each time. Create the generator once and reuse it.

Assuming a standard UUID type exists in C++

As of C++23, there is no std::uuid. A proposal exists but has not been standardized. Always use a library (stduuid or Boost) rather than rolling your own.

How It Works

Both stduuid and Boost.Uuid use std::random_device as the entropy source, which maps to the OS CSPRNG - /dev/urandom on Linux/macOS and BCryptGenRandom on Windows.

The UUID is stored as a 16-byte array (std::array<uint8_t, 16> in stduuid). No heap allocation per UUID - it's a value type.

Output Formats

uuids::to_string(id)

f47ac10b-58cc-4372-a567-0e02b2c3d479

boost::uuids::to_string(id)

f47ac10b-58cc-4372-a567-0e02b2c3d479

Raw bytes

std::array<uint8_t, 16>

Best Practices, Performance, and Security

Best practices

Create the generator once as a static or member variable - reuse it for all UUID generation.

Store UUIDs as the native type (uuids::uuid or boost::uuids::uuid) - only convert to string at output boundaries.

Use stduuid for new projects - it's header-only and requires no Boost dependency.

Performance

C++ generates roughly 10–50 million UUIDs/second with stduuid. The UUID is a 16-byte value type - zero heap allocation per UUID.

The string conversion (uuids::to_string) allocates a std::string. For maximum throughput, keep UUIDs in their binary form and only convert when needed.

Security

Entropy source: std::random_device → OS CSPRNG (/dev/urandom on Linux/macOS, BCryptGenRandom on Windows). Cryptographically secure.

Never use std::mt19937 or rand() for UUID generation - they are not CSPRNG-backed and produce predictable output.

Installation

UUID v4 (boost::uuids)

bash
# stduuid (CMake / vcpkg)
vcpkg install stduuid

# Or copy uuid.h directly (header-only)
bash
# Boost.Uuid (part of Boost)
vcpkg install boost-uuid

stduuid requires C++17. Boost.Uuid requires C++11 and a Boost installation.

Frequently Asked Questions

How do I generate a UUID in C++?

C++ has no standard UUID type yet (as of C++23). The common cross-platform options are stduuid (header-only, C++17) and Boost.UUID, both of which draw entropy from std::random_device. On Windows you can also call UuidCreate(), and on Linux libuuid provides uuid_generate().

Is uuid::generate_v4() cryptographically secure?

Yes. uuid::generate_v4() uses the platform CSPRNG (operating system secure random source), suitable for session tokens, API keys, and idempotency keys. Do not use non-cryptographic random sources for security-sensitive identifiers.

What is the difference between UUID v4 and v7 in C++?

UUID v4 (uuid::generate_v4() or equivalent) is fully random and not sortable. UUID v7 embeds a millisecond timestamp for chronological sorting (RFC 9562). Use v4 for general-purpose IDs; use v7 for database primary keys at scale.

Do I need to install a package for UUID generation in C++?

A package or library install may be required. See the Installation section for the recommended approach in C++.

How do I validate a UUID string in C++?

Use the platform's UUID parse/validation function, or test against the RFC 4122 regex: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i. Always validate external input at API boundaries.

Should I use UUIDs as database primary keys in C++ applications?

UUIDs work well as primary keys for distributed systems. Prefer native UUID/BINARY(16) column types over VARCHAR(36). For very large tables, consider UUID v7 for better B-tree insert locality.

Can I generate UUIDs in C++ without a network connection?

Yes. UUID generation uses local OS entropy sources and does not require network access. Each call is independent and thread-safe on modern platforms.

What output formats are available in C++?

The standard hyphenated lowercase string (36 chars) is the default. Most APIs also support 32-char hex (no hyphens) and 16-byte binary formats. Use string format for APIs and binary for database storage.

What RFC standards apply to C++ UUID generation?

Version 4 UUIDs follow RFC 4122. UUID v7 follows RFC 9562 (May 2024). Ensure your chosen method produces compliant version and variant bits.

When should I avoid UUID v1?

Avoid UUID v1 in security-sensitive contexts - it embeds MAC address and timestamp information. Prefer v4 (uuid::generate_v4() or equivalent) unless you need legacy Cassandra timeuuid compatibility.

Key definitions

UUID
128-bit universally unique identifier, usually shown as 36 hex characters with hyphens.
CSPRNG
Cryptographically secure pseudo-random number generator - the entropy source behind secure UUID generation.
RFC 4122
IETF standard defining UUID versions 1 through 5. Version 4 is random.
RFC 9562
IETF standard adding UUID versions 6, 7, and 8. Version 7 is time-ordered.