如何在 C++ 中生成 UUID,而不使用 boost 库?

Posted

技术标签:

【中文标题】如何在 C++ 中生成 UUID,而不使用 boost 库?【英文标题】:How can I generate UUID in c++, without using boost library? 【发布时间】:2014-08-13 10:59:56 【问题描述】:

我想为我的应用程序生成 UUID 以区分我的应用程序的每次安装。我想在不支持 boost 库的情况下使用 C++ 生成这个 UUID。如何使用其他一些开源库生成 UUID?

注意:我的平台是windows

【问题讨论】:

Qt. 在windows上你可以使用UuidCreate它在rpc.h。例如:nogeekhere.blogspot.in/2008/07/… 加一表示“不使用 boost” 【参考方案1】:

这是一个使用随机库在c++中基于字符串生成唯一uuid的函数,而不使用boost库

std::string generate_uuid(std::string &seedstring)

    auto sum = std::accumulate(seedstring.begin(), seedstring.end(), 0);

    std::mt19937                    gen(sum);
    std::uniform_int_distribution<> dis(0, 15);
    std::uniform_int_distribution<> dis2(8, 11);

    std::stringstream ss;
    ss.clear();
    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);
    ;
    cout << "uuid is" << ss.str() << endl;
    return ss.str();

this function will generate same uuid until seedstring value is same.

【讨论】:

【参考方案2】:

您可以使用我为此开发的rst C++ 库:

#include "rst/guid/guid.h"

std::string guid = rst::Guid().AsString();

// Performs no allocations.
std::cout << rst::Guid().AsStringView().value() << std::endl;

【讨论】:

您链接的 GitHub 项目似乎是您自己的。如果情况,那么您必须明确披露该事实,否则您的帖子可能会被视为垃圾邮件。【参考方案3】:

2021年,我建议使用单头库stduuid。它是跨平台的,不会引入任何不需要的依赖项。

从项目的 github 页面下载uuid.h,然后一个最小的工作示例是:

#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;

有关各种选项和生成器的更多详细信息和文档,请参阅项目的 github 页面。

【讨论】:

这个repo测试好了吗?【参考方案4】:

如果您使用的是现代 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();
    

【讨论】:

我认为值得注意的是,此输出的格式类似于 guid,但不足以成为 guid。 cplusplus.com/reference/random/mt19937 std::mt19937 具有 32 位随机性,或 4E9 组合。真正的 guid 具有 128 位随机性,或 3E38 种组合。真正的 guid 会更加随机 (bil bil bil)x。 mt19937->mt19937_64 将是一种改进,即 64 位随机性或 1.8E19 组合,但就随机性期望而言,仍然不是指导。 一题:32位随机性+32位随机性+....+32位随机性不等于128位随机性??? @RaulLuna 不,因为这是伪随机数生成器,所以所有后续调用都依赖于先前的调用。就像从 int16 制作 SHA256 仍然会产生 65,000 个唯一哈希,而不是 2**256。 std::mt19937 内部包含更多状态位,但这取决于初始状态,因此子序列非常不清楚。真正的 UUID 在唯一性方面要可靠得多。 PRNG 的状态足够大(19937 位),但它完全由 random_device (rd()) 生成的 32 位值播种,因此此函数只能生成 2^32可能的 uuid。否决,不要使用这个或任何类似的答案,否则您可能会引入安全问题,请参阅this question【参考方案5】:

如果你只是想要一些随机的东西,我写了这个小函数:

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;

【讨论】:

@Nina 不保证,但你中彩票后被闪电击中的可能性比发生碰撞的可能性更大。【参考方案6】:

传统上,UUID 只是机器的 MAC 地址,加上自西方采用公历以来的 100 纳秒间隔数。所以写一个 C++ class 来为你做这件事并不难。

【讨论】:

但是我需要根据随机数生成 UUID(类型 4)#Paul。我不能使用 C++ 中可用的普通 rand() 函数。这就是我尝试库文件的原因。 有几个versions and variants of UUIDs;您的回答仅涵盖版本 1。 @user3732956:如果您要执行的操作随机 UUID,为什么不能使用 rand() 或任何其他(伪)随机函数? 是的,去伪随机函数,我想我应该去库文件,对吧。这就是为什么我更喜欢直接使用 UUID 库文件。 这种风格的 UUID(类型 1)已被弃用,取而代之的是不泄露 PII 的 UUID。【参考方案7】:

ossp-uuid 库可以生成 UUID 并具有 C++ 绑定。

使用起来似乎极其简单:

#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;

请注意,它分配并返回一个 C 风格的字符串,调用代码必须解除分配以避免泄漏。

另一种可能性是 libuuid,它是 util-linux 包的一部分,可从ftp://ftp.kernel.org/pub/linux/utils/util-linux/ 获得。任何 Linux 机器都已经安装了它。它没有 C++ API,但仍可使用 C API 从 C++ 调用。

【讨论】:

关于调用 uuid 的 string() 函数的注意事项,它分配的内存必须由调用代码释放!在上面的答案中,调用 id.string() 将 char* 返回到新分配的内存,而不是一个不错的 std::string (通过析构函数/RAII 管理其内存)。所以上面的代码有内存泄漏。最好设置 char* str = id.string() 然后在 str 上调用 delete 一旦完成使用它。 @jCuga 好伤心,我什至没有注意到!谢谢,已更新答案。【参考方案8】:

如cmets中所说,可以使用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;

【讨论】:

#Yuval,我应该下载 rpcrt4.lib 并将该库文件保存在 lib 文件夹中吗?或者 rpcrt4.lib 在 Windows 中可用。不好意思问这么傻的问题 @PURE 这个库包含在 Visual Studio 的安装中 或者使用 CoCreateGuid,它是 UuidCreate 的包装器。 请注意,要链接 rpcrt4.lib,您必须打开项目的属性,转到配置属性 -> 链接器 -> 命令行,然后在附加选项框中键入 Rpcrt4.lib。 #include &lt;rpc.h&gt; 对我来说是必要的(而不是 #include &lt;windows.h&gt;

以上是关于如何在 C++ 中生成 UUID,而不使用 boost 库?的主要内容,如果未能解决你的问题,请参考以下文章

Hive中生成随机唯一标识ID的方法

如何在 SAP UI5 代码中生成 UUID? [复制]

如何在 Python 中生成可重现(带有种子)的随机 UUID

如何在swift中生成设备特定的唯一uuid

如何在jquery中生成uuid

如何在 R 中生成 GUID?