BareGit
#include "non_secret_random.h"

#include <array>
#include <cstddef>
#include <cstdint>
#include <random>
#include <string>

NonSecretRandom::NonSecretRandom()
{
    std::random_device device;
    std::array<std::uint32_t, 8> seeds;
    for(std::uint32_t& seed : seeds)
    {
        seed = device();
    }
    std::seed_seq sequence(seeds.begin(), seeds.end());
    engine_.seed(sequence);
}

NonSecretRandom::NonSecretRandom(std::uint64_t seed)
        : engine_(seed)
{}

std::uint32_t NonSecretRandom::next()
{
    std::lock_guard lock(mutex_);
    std::uniform_int_distribution<std::uint32_t> distribution;
    return distribution(engine_);
}

std::string NonSecretRandom::hex(std::size_t byte_count)
{
    static constexpr char HEX_DIGITS[] = "0123456789abcdef";
    std::lock_guard lock(mutex_);
    std::uniform_int_distribution<unsigned int> distribution(0, 255);
    std::string result;
    result.reserve(byte_count * 2);
    for(std::size_t index = 0; index < byte_count; ++index)
    {
        const unsigned int byte = distribution(engine_);
        result.push_back(HEX_DIGITS[byte >> 4]);
        result.push_back(HEX_DIGITS[byte & 0x0f]);
    }
    return result;
}