如何在不使用boost库的情况下在c ++中生成UUID?

PUR*_*URE 14 c++ uuid

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

注意:我的平台是windows

Sas*_*yal 24

如果您使用的是现代 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为值得注意的是,此输出的格式类似于 guid,但作为 guid 还不够“独特”。http://www.cplusplus.com/reference/random/mt19937/ std::mt19937 有 32 位随机性,或 4E9 组合。真正的 guid 具有 128 位随机性,或 3E38 种组合。真正的 guid 会更加随机。mt19937-&gt;mt19937_64 将是一个改进,它是 64 位随机性,或 1.8E19 组合,但就随机性期望而言,仍然不是一个指导。 (5认同)
  • @RaulLuna 不,因为这是伪随机数生成器,所以所有后续调用都依赖于先前的调用。就像从 int16 生成 SHA256 仍然会产生 65000 个唯一的哈希值,而不是 2**256。std::mt19937 内部包含更多状态位,但这取决于初始状态,因此非常不清楚的子序列。真正的 UUID 在唯一性方面更加可靠。 (3认同)
  • PRNG 具有足够大的状态(19937 位),但它完全由 random_device (`rd()`) 生成的 32 位值作为种子,因此该函数只能生成 2^32 个可能的 uuid。否决,**不要使用这个**或任何类似的答案,否则您可能会引入安全问题,请参阅[此问题](https://codereview.stackexchange.com/questions/109260/seed-stdmt19937-from-stdrandom-设备) (3认同)

Yuv*_*val 12

如评论中所述,您可以使用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;
}
Run Code Online (Sandbox Code Playgroud)

  • `#include &lt;rpc.h&gt;` 对我来说是必要的(而不是 `#include &lt;windows.h&gt;`) (2认同)

Cap*_*man 12

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

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;
}
Run Code Online (Sandbox Code Playgroud)

  • @Nina 不能保证,但中奖后你更有可能被闪电击中,而不是发生碰撞。 (2认同)

ggr*_*cca 7

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

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

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


har*_*mic 5

所述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;
}
Run Code Online (Sandbox Code Playgroud)

请注意,它分配并返回一个 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 。 (2认同)

Pau*_*ans 2

传统上,UUID 只是机器的 MAC 地址与自西方采用公历以来 100 纳秒间隔的数量连接起来。因此,编写一个 C++ 来为您完成此任务并不太困难class