Skip to content

Commit

Permalink
Merge pull request #6985 from n8sh/issue-19836
Browse files Browse the repository at this point in the history
Fix Issue 19836 - Excessive probability of UUID collisions in std.uuid.randomUUID
merged-on-behalf-of: Nicholas Wilson <thewilsonator@users.noreply.github.com>
  • Loading branch information
dlang-bot committed Apr 29, 2019
2 parents 269749d + 5d0f1d3 commit 595a290
Showing 1 changed file with 30 additions and 0 deletions.
30 changes: 30 additions & 0 deletions std/random.d
Expand Up @@ -1813,6 +1813,8 @@ A singleton instance of the default random number generator
{
static if (isSeedable!(Random, ulong))
result.seed(unpredictableSeed!ulong); // Avoid unnecessary copy.
else static if (size_t.sizeof >= ulong.sizeof && is(Random : MersenneTwisterEngine!Params, Params...))
initMTEngine(result); // 64-bit multiplication is fast, so use a 64-bit seed.
else static if (isSeedable!(Random, uint))
result.seed(unpredictableSeed!uint); // Avoid unnecessary copy.
else
Expand All @@ -1831,6 +1833,34 @@ A singleton instance of the default random number generator
assert(rnd.take(3).sum > 0);
}

/+
Initialize a 32-bit MersenneTwisterEngine from 64 bits of entropy.
This is private and accepts no seed as a parameter, freeing the internal
implementaton from any need for stability across releases.
+/
private void initMTEngine(MTEngine)(scope ref MTEngine mt)
if (is(MTEngine : MersenneTwisterEngine!Params, Params...))
{
pragma(inline, false); // Called no more than once per thread by rndGen.
ulong x = unpredictableSeed!ulong;
alias UIntType = typeof(mt.front());
foreach (size_t i, ref e; mt.state.data)
{
x = (x ^ (x >> 62)) * 6_364_136_223_846_793_005UL + i;
e = cast(UIntType) x;
static if (MTEngine.max != UIntType.max)
{
e &= MTEngine.max;
}
}
mt.state.index = mt.state.data.length - 1;
// double popFront() to guarantee both `mt.state.z`
// and `mt.state.front` are derived from the newly
// set values in `mt.state.data`.
mt.popFront();
mt.popFront();
}

/**
Generates a number between `a` and `b`. The `boundaries`
parameter controls the shape of the interval (open vs. closed on
Expand Down

0 comments on commit 595a290

Please sign in to comment.