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:
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?
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 toboost::endian::native_to_big
to invokeboost::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
Forcing String to Int Function to Consume Entire String
How to Keep My Topmost Window on Top
How Is This a Most Vexing Parse
How to Check If Std::Map Contains a Key Without Doing Insert
What Happens When an Exception Goes Unhandled in a Multithreaded C++11 Program
How to Resume Input Stream After Stopped by Eof in C++
Retrieving a C++ Class Name Programmatically
The Difference Between C and C++ Regarding the ++ Operator
C++11 Cross Compiler/Standard Library Random Distribution Reproducibility
What Is the Role of Glbindvertexarrays VS Glbindbuffer and What Is Their Relationship
Benefits and Portability of Boost Library
Strange Behaviour of MACros C/C++
Rodrigues into Eulerangles and Vice Versa