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