How can I generate UUID in c++, without using boost library?

78,686

Solution 1

This will do, if you're using modern C++.

#include <random>
#include <sstream>

namespace uuid {
    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::string generate_uuid_v4() {
        std::stringstream ss;
        int i;
        ss << std::hex;
        for (i = 0; i < 8; i++) {
            ss << dis(gen);
        }
        ss << "-";
        for (i = 0; i < 4; i++) {
            ss << dis(gen);
        }
        ss << "-4";
        for (i = 0; i < 3; i++) {
            ss << dis(gen);
        }
        ss << "-";
        ss << dis2(gen);
        for (i = 0; i < 3; i++) {
            ss << dis(gen);
        }
        ss << "-";
        for (i = 0; i < 12; i++) {
            ss << dis(gen);
        };
        return ss.str();
    }
}

Solution 2

As mentioned in the comments, you can use UuidCreate

#pragma comment(lib, "rpcrt4.lib")  // UuidCreate - Minimum supported OS Win 2000
#include <windows.h>
#include <iostream>

using namespace std;

int main()
{
    UUID uuid;
    UuidCreate(&uuid);
    char *str;
    UuidToStringA(&uuid, (RPC_CSTR*)&str);
    cout<<str<<endl;
    RpcStringFreeA((RPC_CSTR*)&str);
    return 0;
}

Solution 3

If you just want something random, I wrote this small function:

string get_uuid() {
    static random_device dev;
    static mt19937 rng(dev());

    uniform_int_distribution<int> dist(0, 15);

    const char *v = "0123456789abcdef";
    const bool dash[] = { 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0 };

    string res;
    for (int i = 0; i < 16; i++) {
        if (dash[i]) res += "-";
        res += v[dist(rng)];
        res += v[dist(rng)];
    }
    return res;
}

Solution 4

The ossp-uuid library can generate UUIDs and has C++ bindings.

It seems extremely simple to use:

#include <uuid++.hh>
#include <iostream>

using namespace std;

int main() {
        uuid id;
        id.make(UUID_MAKE_V1);
        const char* myId = id.string();
        cout << myId << endl;
        delete myId;
}

Note that it allocates and returns a C-style string, which the calling code must deallocate to avoid a leak.

Another possibility is libuuid, which is part of the util-linux package, available from ftp://ftp.kernel.org/pub/linux/utils/util-linux/. Any Linux machine will have it installed already. It does not have a C++ API but is still callable from C++ using the C API.

Solution 5

In 2021, I suggest to use the single-header library stduuid. It's cross-platform and it does not bring in any unwanted dependencies.

Download uuid.h from the project's github page, then a minimal working example is:

#include <iostream>
#include <string>

#define UUID_SYSTEM_GENERATOR
#include "uuid.h"

int main (void) {
    std::string id = uuids::to_string (uuids::uuid_system_generator{}());
    std::cout << id << std::endl;
}

See the project's github page for more details and documentation on various options and generators.

Share:
78,686
PURE
Author by

PURE

Updated on December 01, 2021

Comments

  • PURE
    PURE over 2 years

    I want to generate UUID for my application to distinguish each installation of my application. I want to generate this UUID using C++ without boost library support. How can I generate UUID using some other opensource library?

    Note: My platform is windows

  • PURE
    PURE almost 10 years
    But I need to generate UUID (type 4) based on random numbers, #Paul. I coudn't use normal rand() function available in C++. Thant is why I trying for library files.
  • Angew is no longer proud of SO
    Angew is no longer proud of SO almost 10 years
    There's several versions and variants of UUIDs; your answer only covers Version 1.
  • DevSolar
    DevSolar almost 10 years
    @user3732956: Why can't you use rand() or any other (pseudo-) random function, if what you are trying to do is a random UUID?
  • PURE
    PURE almost 10 years
    #Yuval, should I download rpcrt4.lib and keep that library files in lib folder?, or else rpcrt4.lib is available in windows. sorry to ask such silly question
  • Yuval
    Yuval almost 10 years
    @PURE this library is included with the installation of Visual Studio
  • PURE
    PURE almost 10 years
    ya, to go pseudo random function, I think I should go to library files, right. that is why I prefer directly UUID library files.
  • JoeG
    JoeG almost 10 years
    This style of UUID (type 1) has been abandoned in favour of UUIDs that don't leak PII.
  • jCuga
    jCuga over 8 years
    A word of caution about calling uuid's string() function, this allocates memory that must be deallocated by the calling code! In the above answer, calling id.string() returns a char* to newly allocated memory, not a nice std::string (which manages its memory via destructor/RAII). So the above code has a memory leak. It would be better to set char* str = id.string() and then call delete on str once finished using it.
  • harmic
    harmic over 8 years
    @jCuga good grief, I didn't even notice that! Thanks, have updated the answer.
  • gast128
    gast128 almost 7 years
    Or use CoCreateGuid which is a wrapper around UuidCreate.
  • Basile Starynkevitch
    Basile Starynkevitch over 6 years
    C++11 has <random>, much better than rand()
  • BinaryNate
    BinaryNate over 4 years
    Note than in order to link rpcrt4.lib, you must open your project's properties, go to Configuration Properties -> Linker -> Command Line, and then type Rpcrt4.lib into the Additional Options box.
  • CaptainCodeman
    CaptainCodeman over 4 years
    @Nina No guarantee, but you are more likely to get struck by lightning after wining the lottery than have a collision.
  • user4851
    user4851 about 4 years
    #include <rpc.h> was necessary for me (instead of #include <windows.h>)
  • Paul Gilmore
    Paul Gilmore over 3 years
    I think it's worth noting, this output is formatted like a guid, but isn't "unique enough" to be a guid. cplusplus.com/reference/random/mt19937 std::mt19937 has 32 bits of randomness, or 4E9 combinations. A true guid has 128 bits of randomness, or 3E38 combinations. A true guid would be a (bil bil bil)x more random. mt19937->mt19937_64 would be an improvement, which is 64 bits of randomness, or 1.8E19 combinations, but still wouldn't be a guid, in terms of the randomness expectation.
  • Raul Luna
    Raul Luna over 3 years
    one question: 32 bits of randomness + 32 bits of randomnes + .... + 32 bits of randomness is not equal to 128 bits of randomness???
  • Konstantine Kozachuck
    Konstantine Kozachuck over 3 years
    @RaulLuna No, as this is pseudo-random number generator, so all subsequent invocations depend on previous. Like making SHA256 from int16 will still produce 65 thousands of unique hashes, not 2**256. std::mt19937 contains more bits of state inside, but that depends on initial state, so very unclear subsequences. Real UUIDs are much more reliable in terms of uniqueness.
  • Alba Mendez
    Alba Mendez about 3 years
    the PRNG has a large enough state (19937 bits) but it is being seeded entirely by a 32-bit value generated by the random_device (rd()) so this function can only ever generate 2^32 possible uuids. downvoted, do NOT use this or any similar answer or you could introduce a security issue, see this question
  • Djvu
    Djvu over 2 years
    does this repo get test well?
  • Adrian Mole
    Adrian Mole over 2 years
    The GitHub project you've linked appears to be your own. If this is the case, then you must explicitly disclose that fact, or your post may be considered as spam.
  • ScaryAardvark
    ScaryAardvark about 2 years
    This library appears to use the std::mt19937 so I think it still fails the "unique enough" issue already discussed on this question.
  • Adrian Maire
    Adrian Maire about 2 years
    Isn't this answer kind of plagia of the first answer?