简体   繁体   中英

How can I generate UUID in c++, without using boost library?

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

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();
    }
}

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

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

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.

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.

Traditionally UUID's are simply the machine's MAC address concatenated with with the number of 100-nanosecond intervals since the adoption of the Gregorian calendar in the West. So it's not too difficult to write a C++ class that does this for you.

You can use the rst C++ library that I developed to do that:

#include "rst/guid/guid.h"

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

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

Here is a function to generate unique uuid based on string in c++ using random library, without using boost library

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.

This code works for me :).

#pragma comment(lib, "rpcrt4.lib") 
#include <windows.h>
#include <rpcdce.h>
/*
* Generate a Universal Unique Identifier using windows api.
* Note: throw exceptions if uuid wasn't created successfully.
*/
std::string generate_uuid()
{
    UUID uuid;
    RPC_CSTR  uuid_str;
    std::string uuid_out;

    if (UuidCreate(&uuid) != RPC_S_OK)
        std::cout << "couldn't create uuid\nError code" << GetLastError() << std::endl;

    if (UuidToStringA(&uuid, &uuid_str) != RPC_S_OK)
        std::cout << "couldn't convert uuid to string\nError code" << GetLastError() << std::endl;

    uuid_out = (char*)uuid_str;
    RpcStringFreeA(&uuid_str);
    return uuid_out;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM