在C++中生成平台无关的GUID?

60

如何在不依赖平台特定工具的情况下以C++编程语言生成GUID或UUID的最佳方法? 我正在尝试为模拟中的对象生成唯一标识符,但由于该项目是跨平台的,因此不能依赖Microsoft的实现。

备注:

  • 由于这是用于模拟器,因此我并不需要加密随机性。
  • 最好使用32位数字。

这个编程问题的答案:https://dev59.com/zXRB5IYBdhLWcg3wtZIV 给了我一个更好的答案。 - Vivian De Smedt
GUID(全局唯一标识符)是一个128位的数字。如果需要,您可以从中取32位,但不能保证其唯一性或随机性。 - Mark Ransom
6个回答

48
如果您可以使用Boost,那么有一个UUID库可以解决问题。它非常易于使用-请查看文档和这个答案。请保留HTML标记:

如果您可以负担得起使用Boost,那么有一个UUID库可以解决问题。它非常简单易用-请查看文档和此答案


这正是我所期望的。谢谢。 - Moses Schwartz
阅读讨论并查看代码,我无法阻止感觉这仍然是非常初步的。特别是,API 更改,并且缺少基于时间的UUID创建。话虽如此,这种方法很好且适应性强,实现也很稳定(除了一个已知的竞争条件)。 - Konrad Rudolph
是的,至少有两次后续讨论 - 其中一个与接口、lexical_cast等问题有关,另一个则涉及PODness。我没有跟进它们。 - Anonymous
嗨,anon,这两个问题(PODness和lex_cast)现在都已经得到了优雅的解决。:-) 无论如何,我很高兴你首先发布了这个参考:我可以并且会充分利用它。我相信未解决的问题很快就会得到解决。 - Konrad Rudolph
请更新您的答案,因为该库已被接受为 Boost 家族的一员。 - Artem Oboturov
1
可以独立于Boost使用该库吗?对我来说,为了获取Guids而将Boost添加到项目中太过沉重! - sergiol

43
在Linux上:输入命令"man uuid"
在Windows上:查看MSDN中的UUID结构和UuidCreate函数
[编辑] 函数应该长这样
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;
}

注意:在Visual Studio C++中,“禁用语言扩展”必须设置为NO。尽管如此,我仍然遇到了未解决的外部错误。我需要包含哪些库,以及如何包含它们? - Jive Dadson
1
rpcrt4是你所需要的库。那段代码无论如何都是使用gcc + mingw编译的。 - ubik
关于 rpcrt4.lib 链接问题:SO: 如何解决调用 ::UuidToString() 时的链接错误? - Scheff's Cat

15
如果您无法使用Boost,那么有一个我实现的极简库,只是充当每个操作系统本地guid实现的包装器。它应该适用于Windows(使用CoCreateGuid),Linux(使用libuuid),MacOS(使用CFUUID),iOS(也使用CFUUID )和Android(使用JNI调用java.util.UUID)。每个系统上的guid生成函数具有不同的实现,但有单一通用的实现来进行比较、字符化和解析。
这个库采用MIT许可证,并且在GitHub上可用: https://github.com/graeme-hill/crossguid

2

在目标平台上使用现有的guid/uuid是最好的。正确地实现这一点很难(让我们去购物;)。

来自不同但执行良好的实现的任何两个标识符之间发生冲突的概率应该远远超出本宇宙寿命内发生任何合理机会的范围。


1
如果您想在32位数字中获得独特性(无需合作),那么您将面临问题。将范围进行分区并根据需要分配它们是唯一的方法... - ShuggyCoUk

1
GUID生成器通常依赖于机器的硬件特征,例如MAC地址或IP地址。唯一可以做到绝对平台无关的事情是使用某种手动种子或从某个时间源播种的PRNG。这通常不会生成真正的全局唯一标识符,因为您不能保证世界上没有人生成相同的数字。

-3

一个不太常规的解决方案是使用 Web 服务获取 GUID,但我怀疑这对于 C++ 程序来说并不是一个好的解决方案,特别是如果它没有启用网络功能。

如果您选择追求这个选项,这里有一个可能会有用的 URL: http://www.hoskinson.net/GuidGenerator/default.asp


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接