mirror of
https://github.com/dlang/phobos.git
synced 2025-04-26 21:22:20 +03:00
This commit is contained in:
parent
e1d9d0208b
commit
b150fde4da
1 changed files with 43 additions and 20 deletions
63
std/uuid.d
63
std/uuid.d
|
@ -1204,32 +1204,55 @@ public struct UUID
|
|||
*
|
||||
* This function is not supported at compile time.
|
||||
*
|
||||
* Bugs:
|
||||
* $(LINK2
|
||||
* https://github.com/dlang/phobos/issues/9881
|
||||
* Issue #9881 - Randomness in UUID generation is insufficient
|
||||
* )
|
||||
*
|
||||
* Warning:
|
||||
* $(B This function must not be used for cryptographic purposes.)
|
||||
* UUIDs generated by this function do not have sufficient randomness
|
||||
* for all use cases.
|
||||
* This especially applies to the overload that accepts a caller-provided RNG.
|
||||
* At the moment, Phobos does not provide a $(I cryptographically-secure
|
||||
* pseudo-random number generator (CSPRNG)) that could be supplied to this
|
||||
* function.
|
||||
*
|
||||
* While the function overload with no parameters will attempt to use the
|
||||
* system CSPRNG where available and implemented, there are no guarantees.
|
||||
* See $(REF unpredictableSeed, std, random) for details.
|
||||
*
|
||||
* Params:
|
||||
* randomGen = uniform RNG
|
||||
* See_Also: $(REF isUniformRNG, std,random)
|
||||
*/
|
||||
@nogc nothrow @safe UUID randomUUID()
|
||||
{
|
||||
import std.random : rndGen;
|
||||
// A PRNG with fewer than `n` bytes of state cannot produce
|
||||
// every distinct `n` byte sequence.
|
||||
static if (typeof(rndGen).sizeof >= UUID.sizeof)
|
||||
{
|
||||
return randomUUID(rndGen);
|
||||
}
|
||||
else
|
||||
{
|
||||
import std.random : unpredictableSeed, Xorshift192;
|
||||
static assert(Xorshift192.sizeof >= UUID.sizeof);
|
||||
static Xorshift192 rng;
|
||||
static bool initialized;
|
||||
if (!initialized)
|
||||
{
|
||||
rng.seed(unpredictableSeed);
|
||||
initialized = true;
|
||||
}
|
||||
return randomUUID(rng);
|
||||
}
|
||||
import std.conv : bitCast;
|
||||
import std.random : unpredictableSeed;
|
||||
|
||||
enum bufferSize = UUID.data.sizeof;
|
||||
ubyte[bufferSize] data;
|
||||
|
||||
static assert(ulong.sizeof * 2 == bufferSize);
|
||||
const half1 = unpredictableSeed!ulong();
|
||||
const half2 = unpredictableSeed!ulong();
|
||||
|
||||
data[0 .. ulong.sizeof] = (() @trusted => half1.bitCast!(ubyte[ulong.sizeof]))();
|
||||
data[ulong.sizeof .. $] = (() @trusted => half2.bitCast!(ubyte[ulong.sizeof]))();
|
||||
|
||||
// set variant
|
||||
// must be 0b_10xxxxxx
|
||||
data[8] &= 0b_10_111111;
|
||||
data[8] |= 0b_10_000000;
|
||||
|
||||
// set version
|
||||
// must be 0b_0100xxxx
|
||||
data[6] &= 0b_0100_1111;
|
||||
data[6] |= 0b_0100_0000;
|
||||
|
||||
return UUID(data);
|
||||
}
|
||||
|
||||
/// ditto
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue