Boost logo

Boost :

Subject: Re: [boost] Boost.Uuid and header-only support
From: James E. King, III (jking_at_[hidden])
Date: 2017-11-06 17:20:11


On Mon, Nov 6, 2017 at 11:10 AM, Steven Watanabe via Boost <
boost_at_[hidden]> wrote:

>
> uniform_int_distribution is not excess weight. You could
> use independent_bits_engine instead, but if you accept
> an arbitrary random engine, then you need some way to
> convert its output into the correct range. Not all engines
> produce uniformly distributed 32-bit output.
>

Filling a uuid with random does not require integers.
In this case as long as the UniformRandomNumberGenerator produces at least
one byte from operator() then it is sufficient to fill the contents of a
uuid randomly.
If it returns more than that, it will be more efficient.

I have a macro that makes a header-only random_device type and it is used
as follows:

namespace detail {
    BOOST_TTI_HAS_MEMBER_FUNCTION(seed)
}
    template<class MaybePseudoRandomNumberGenerator>
    typename
boost::enable_if<detail::has_member_function_seed<MaybePseudoRandomNumberGenerator,
void> >::type
    seed(MaybePseudoRandomNumberGenerator& rng)
    {
        BOOST_UUID_DETAIL_MAKE_RANDOM_DEVICE_TYPE(unsigned int,
seed_random_device);

        using boost::function_input_iterator;
        using boost::make_function_input_iterator;

        boost::infinite inf;
        seed_random_device egen;
        function_input_iterator<seed_random_device, boost::infinite> beg =
make_function_input_iterator(egen, inf);
        function_input_iterator<seed_random_device, boost::infinite> end =
make_function_input_iterator(egen, inf);
        rng.seed(beg, end);
    }

internally this is used to obtain seeding for PRNGs.

One can use this in various ways, and it is not limited to the unsigned int
size, for example:

BOOST_UUID_DETAIL_MAKE_RANDOM_DEVICE_TYPE(uuid, uuid_random_device);
typedef basic_random_generator<uuid_random_device> random_generator;

Now the random_generator obtains 16 bytes of entropy in a single call,
rather than making 4 calls for 4 bytes each.

This technique might be applicable to the existing PRNGs in Boost.Random
with a header-only
random_device implementation. For example it may be possible to have the
mersenne twister
make one entropy call for 623 bytes instead of making 156 calls for 4 bytes
at a time. I haven't
looked in detail at the way it seeds itself, however:

struct mersenne_entropy_pod
{
    uint8_t entropy[623];
}

BOOST_UUID_DETAIL_MAKE_RANDOM_DEVICE_TYPE(mersenne_entropy_pod,
mersenne_seed_random_device);
Then mersenne_twister could call mersenne_seed_random_device()() to get 623
bytes of entropy in a single system call.

- Jim


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk