60

What is the best way to programmatically generate a GUID or UUID in C++ without relying on a platform-specific tool? I am trying to make unique identifiers for objects in a simulation, but can't rely on Microsoft's implementation as the project is cross-platform.

Notes:

  • Since this is for a simulator, I don't really need cryptographic randomness.
  • It would be best if this is a 32 bit number.
Moses Schwartz
  • 6,879
  • 3
  • 21
  • 11
  • The answer to the [question]: http://stackoverflow.com/questions/543306/platform-independent-guid-generation-in-c give to me a better answer. – Vivian De Smedt Sep 28 '12 at 00:02
  • A GUID is [by definition](https://en.wikipedia.org/wiki/Globally_unique_identifier) a 128-bit number. If you wish you can always take 32 bits from one, but it's not guaranteed to be unique or even random. – Mark Ransom Dec 16 '16 at 15:22

6 Answers6

48

If you can afford to use Boost, then there is a UUID library that should do the trick. It's very straightforward to use - check the documentation and this answer.

Community
  • 1
  • 1
Anonymous
  • 18,162
  • 2
  • 41
  • 64
  • This is exactly what I was hoping for. Thanks – Moses Schwartz Feb 12 '09 at 21:36
  • Reading the discussion and looking at the code I can't prevent the feeling that this is still very preliminary. In particular, the API *will* change and it lacks time-based UUID creation. That said, the approach is good and adaptable and the implementation is solid (except for one noted race cond.). – Konrad Rudolph Feb 13 '09 at 08:51
  • Yes, there were at least two follow up discussions - one of the issues related with interfaces, lexical_cast, etc, and the other was about PODness. I did not follow them. – Anonymous Feb 13 '09 at 09:25
  • Hi anon, these two issues (PODness and lex_cast) have both been resolved by now, and very elegantly. :-) Anyway, I'm very happy that you've posted this reference in the first place: I can and will make ample use of it. I'm confident that the outstanding issues will be resolved soon. – Konrad Rudolph Feb 13 '09 at 16:37
  • Please update your answer since the library was accepted to the Boost family. – Artem Oboturov Oct 28 '13 at 15:09
  • 1
    Is it possible to use the library independently of Boost? It seems to me too much overweight to add Boost to a project, just to get Guids! – sergiol Apr 29 '16 at 17:03
43

on linux: man uuid

on win: check out for UUID structure and UuidCreate function in msdn

[edit] the function would appear like this

extern "C"
{
#ifdef WIN32
#include <Rpc.h>
#else
#include <uuid/uuid.h>
#endif
}

std::string newUUID()
{
#ifdef WIN32
    UUID uuid;
    UuidCreate ( &uuid );

    unsigned char * str;
    UuidToStringA ( &uuid, &str );

    std::string s( ( char* ) str );

    RpcStringFreeA ( &str );
#else
    uuid_t uuid;
    uuid_generate_random ( uuid );
    char s[37];
    uuid_unparse ( uuid, s );
#endif
    return s;
}
ubik
  • 595
  • 5
  • 16
  • Note: In Visual Studio C++, "disable language extensions" has to be set to NO. Still, I am getting unresolved extern errors. What libraries do I have to include, and how? – Jive Dadson Aug 25 '12 at 16:23
  • 1
    rpcrt4 is the lib you need. That code was compiled with gcc + mingw anyway. – ubik Sep 19 '12 at 20:30
  • Concerning the `rpcrt4.lib` link issue: [SO: How to solve Link Error on call to ::UuidToString()?](https://stackoverflow.com/a/1991961/7478597) – Scheff's Cat Apr 30 '19 at 11:48
15

If you cannot afford to use Boost, then there is a very minimal library that I implemented which simply acts as a wrapper around each operating system's native guid implementation. It should work on Windows (using CoCreateGuid), Linux (using libuuid), MacOS (using CFUUID), iOS (also using CFUUID), and Android (using JNI calls to java.util.UUID). The guid generation function has a different implementation on each system but there is single generic implementation for comparing, stringifying, and parsing.

It is MIT licensed and available on GitHub:

https://github.com/graeme-hill/crossguid

Graeme Hill
  • 623
  • 6
  • 11
2

Simply using whatever guid/uuid is present on the target platform is best. Doing it right is hard (let's go shopping ;)).

The probability of a collision between any two identifiers from different but well executed implementations should be well beyond any reasonable chance of happening in this universe's lifetime.

ShuggyCoUk
  • 36,004
  • 6
  • 77
  • 101
  • 1
    if you want uniqueness in a 32 bit number (without co-operation) you have a problem. Partitioning the range and assigning them out as needed is about the only way... – ShuggyCoUk Feb 12 '09 at 21:29
1

A GUID generator usually relies on hardware characteristics of the machine, usually stuff like MAC addresses or IPs. The only thing you can do which is absolutely platform independent is use some kind of PRNG seeded manually or seeded from some time source. This usually does not generate a true globally unique identifier in the sense that you are guaranteed that no one in the world generates the same number.

shoosh
  • 76,898
  • 55
  • 205
  • 325
-3

Well one offbeat(?) solution would be to use a web service to get the GUID but I doubt this will be a good solution for a C++ program especially if it's not network enabled.

Here is a URL which might come in handy if you choose to pursue this option: http://www.hoskinson.net/GuidGenerator/default.asp

Sandeep Datta
  • 28,607
  • 15
  • 70
  • 90