How can I generate UUID in c++, without using boost library?
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.
PURE
Updated on December 01, 2021Comments
-
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 almost 10 yearsBut 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 almost 10 yearsThere's several versions and variants of UUIDs; your answer only covers Version 1.
-
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 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 almost 10 years@PURE this library is included with the installation of Visual Studio
-
PURE almost 10 yearsya, to go pseudo random function, I think I should go to library files, right. that is why I prefer directly UUID library files.
-
JoeG almost 10 yearsThis style of UUID (type 1) has been abandoned in favour of UUIDs that don't leak PII.
-
jCuga over 8 yearsA 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 over 8 years@jCuga good grief, I didn't even notice that! Thanks, have updated the answer.
-
gast128 almost 7 yearsOr use CoCreateGuid which is a wrapper around UuidCreate.
-
Basile Starynkevitch over 6 yearsC++11 has
<random>
, much better thanrand()
-
BinaryNate over 4 yearsNote 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 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 about 4 years
#include <rpc.h>
was necessary for me (instead of#include <windows.h>
) -
Paul Gilmore over 3 yearsI 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 over 3 yearsone question: 32 bits of randomness + 32 bits of randomnes + .... + 32 bits of randomness is not equal to 128 bits of randomness???
-
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 about 3 yearsthe 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 over 2 yearsdoes this repo get test well?
-
Adrian Mole over 2 yearsThe 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 about 2 yearsThis library appears to use the std::mt19937 so I think it still fails the "unique enough" issue already discussed on this question.
-
Adrian Maire about 2 yearsIsn't this answer kind of plagia of the first answer?