Files
YarikStudio/AssetStudio/Crypto/MT19937_64.cs
2023-01-07 21:52:15 +04:00

74 lines
2.0 KiB
C#

namespace AssetStudio
{
public class MT19937_64
{
private const ulong N = 312;
private const ulong M = 156;
private const ulong MATRIX_A = 0xB5026F5AA96619E9L;
private const ulong UPPER_MASK = 0xFFFFFFFF80000000;
private const ulong LOWER_MASK = 0X7FFFFFFFUL;
private readonly ulong[] mt = new ulong[N + 1];
private ulong mti = N + 1;
public MT19937_64(ulong seed)
{
Init(seed);
}
public void Init(ulong seed)
{
mt[0] = seed;
for (mti = 1; mti < N; mti++)
{
mt[mti] = 6364136223846793005L * (mt[mti - 1] ^ (mt[mti - 1] >> 62)) + mti;
}
}
public ulong Int64()
{
ulong x;
ulong[] mag01 = new ulong[2] { 0x0UL, MATRIX_A };
if (mti >= N)
{
ulong kk;
if (mti == N + 1)
{
Init(5489UL);
}
for (kk = 0; kk < (N - M); kk++)
{
x = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
mt[kk] = mt[kk + M] ^ (x >> 1) ^ mag01[x & 0x1UL];
}
for (; kk < N - 1; kk++)
{
x = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
mt[kk] = mt[kk - M] ^ (x >> 1) ^ mag01[x & 0x1UL];
}
x = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
mt[N - 1] = mt[M - 1] ^ (x >> 1) ^ mag01[x & 0x1UL];
mti = 0;
}
x = mt[mti++];
x ^= (x >> 29) & 0x5555555555555555L;
x ^= (x << 17) & 0x71D67FFFEDA60000L;
x ^= (x << 37) & 0xFFF7EEE000000000L;
x ^= (x >> 43);
return x;
}
public long Int63()
{
return (long)(Int64() >> 1);
}
public ulong IntN(ulong value)
{
return (ulong)Int63() % value;
}
}
}