#include "random_provider.h" #include #include #include namespace { void SetV4(TGUID& g) { g.dw[1] &= 0x0fffffff; g.dw[1] |= 0x40000000; g.dw[2] &= 0xffffff3f; g.dw[2] |= 0x00000080; } } class TDefaultRandomProvider: public IRandomProvider { public: ui64 GenRand() noexcept override { return RandomNumber(); } TGUID GenGuid() noexcept override { TGUID ret; CreateGuid(&ret); return ret; } TGUID GenUuid4() noexcept override { TGUID ret; WriteUnaligned(ret.dw, RandomNumber()); WriteUnaligned(ret.dw + 2, RandomNumber()); SetV4(ret); return ret; } }; class TDeterministicRandomProvider: public IRandomProvider { public: TDeterministicRandomProvider(ui64 seed) : Gen(seed) { } ui64 GenRand() noexcept override { return Gen.GenRand(); } TGUID GenGuid() noexcept override { TGUID ret; WriteUnaligned(ret.dw, Gen.GenRand()); ret.dw[2] = (ui32)Gen.GenRand(); ret.dw[3] = ++GuidCount; return ret; } TGUID GenUuid4() noexcept override { TGUID ret; WriteUnaligned(ret.dw, Gen.GenRand()); WriteUnaligned(ret.dw + 2, Gen.GenRand()); SetV4(ret); return ret; } private: TMersenne Gen; ui32 GuidCount = 0; }; TIntrusivePtr CreateDefaultRandomProvider() { return TIntrusivePtr(new TDefaultRandomProvider()); } TIntrusivePtr CreateDeterministicRandomProvider(ui64 seed) { return TIntrusivePtr(new TDeterministicRandomProvider(seed)); }