namespace NHSE.Core
{
///
/// Xorshift128 RNG Implementation (xor128)
///
///
internal ref struct XorShift128
{
private uint a, b, c, d;
private const int Mersenne = 0x6C078965;
///
/// Initialize the generator from a seed.
///
/// Ticks, usually.
public XorShift128(uint seed)
{
// Unrolled Mersenne Twister initialization loop
a = (Mersenne * (seed ^ (seed >> 30))) + 1;
b = (Mersenne * ( a ^ ( a >> 30))) + 2;
c = (Mersenne * ( b ^ ( b >> 30))) + 3;
d = (Mersenne * ( c ^ ( c >> 30))) + 4;
}
public uint GetU32()
{
uint t = a;
a = b;
b = c;
c = d;
t ^= t << 11;
t ^= t >> 8;
return d = t ^ d ^ (d >> 19);
}
public ulong GetU64() => ((ulong)GetU32() << 32) | GetU32();
}
}