Example of Uuid Generation Using Boost in C++

Example of UUID generation using Boost in C++

A basic example:

#include <boost/uuid/uuid.hpp>            // uuid class
#include <boost/uuid/uuid_generators.hpp> // generators
#include <boost/uuid/uuid_io.hpp> // streaming operators etc.

int main() {
boost::uuids::uuid uuid = boost::uuids::random_generator()();
std::cout << uuid << std::endl;
}

Example output:

7feb24af-fc38-44de-bc38-04defc3804de

Generate boost::uuids::uuid from boost::compute::detail::sha1

The proper, supported approach to getting a UUID from the SHA1 hash of an arbitrary string is as follows:

#include <string_view>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/name_generator_sha1.hpp>

boost::uuids::uuid uuid_from_string(std::string_view const input) {
static constexpr boost::uuids::uuid ns_id{}; // †null root, change as necessary
return boost::uuids::name_generator_sha1{ns_id}(input.data(), input.size());
}

Online Demo

(std::string_view is used for exposition; use std::string or char const* or whatever as appropriate if this isn't ideal for you.)

While this is the correct approach, there are two important notes:

  1. As per RFC 4122, you need to provide a namespace for your UUID; basically this is salt for your SHA1 hash. There are predefined namespaces for DNS names, URLs, ISO OIDs, and X.500 distinguished names, but as your input doesn't appear to match any of those you need to define your own; as indicated on the line marked †, the null namespace is used here for exposition. A more detailed explanation of UUID namespaces can be found in this SO answer: Generating v5 UUID. What is name and namespace?

  2. The output from this code will differ entirely from the output from the code in your question; iff you need the output to match the old code you can do the following:

    #include <cstring>
    #include <string_view>
    #include <boost/endian/conversion.hpp>
    #include <boost/uuid/uuid.hpp>
    #include <boost/uuid/detail/sha1.hpp>

    boost::uuids::uuid uuid_from_string_old(std::string_view const input) {
    boost::uuids::detail::sha1::digest_type digest;
    {
    boost::uuids::detail::sha1 h;
    h.process_bytes(input.data(), input.size());
    h.get_digest(digest);
    }

    boost::uuids::uuid ret;
    auto p = ret.begin();
    for (std::size_t i{}; i != 4; p += 4, ++i) {
    auto const d = boost::endian::native_to_big(digest[i]);
    std::memcpy(p, &d, 4);
    }
    return ret;
    }

    Online Demo

    This produces the same output, as can be seen from this demo using the old code with Boost 1.65.1. This goes against my commented policy of never directly using someone else's detail namespace, but unless you can find the magic namespace id (if one exists), this is the only approach using Boost that I'm aware of. N.b. this fixes a bug in the old Boost code for big-endian machines; if you need to retain that bug, change the call to boost::endian::native_to_big to invoke boost::endian::endian_reverse instead.

How to pass Boost UUID random generator output to main

Generate them into a standard library container, such as e.g. std::vector<uuid>:

std::vector<uuid> foo() {
std::vector<uuid> r;
std::generate_n(back_inserter(r), 40, random_generator());
return r;
}

Live On Coliru

#include <boost/uuid/uuid.hpp>            
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <iostream>

using namespace std;
using namespace boost;
using namespace uuids;

std::vector<uuid> foo() {
std::vector<uuid> r;
std::generate_n(back_inserter(r), 40, random_generator());
return r;
}

int main() {
for(auto& uuid : foo())
cout << uuid << endl;
}

generate a boost.uuid from a boost.path string

Based on the code in the header the code does not generate hashes but instead parses a UUID-as-string and converts it to a uuid.

It sounds like you are looking for a hash based on the path, which is not the same as a UUID. UUIDs are intended to be unique, implying that e.g. one could have paths of the same value stored in an associative container under different UUIDs.

You might be better off looking at Boost.Hash.

Are boost UUIDs generated using default mt19937 RNG secure for session IDs?

MT is not a cryptographically secure RNG.

boost::random_device is guaranteed (by docs) to only exist if cruptographically secure and non-deterministic. Note that this is not true of std::random_device.

For any serious application, you cannot trust a mere documented guarantee. But for a small scale unimportant one it should do.

Writing your own cryptographically secure code or system is usually a bad idea. Describe how bad it is that someone defeat your system, as that really matters to how much effort you need to put into it.



Related Topics



Leave a reply



Submit