using System; using System.Numerics; using System.Runtime.InteropServices; namespace LibHac.Tests; public struct Random { private ulong _state1; private ulong _state2; public Random(ulong seed) { unchecked { ulong x = seed; ulong z = x + 0x9e3779b97f4a7c15; z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; z = (z ^ (z >> 27)) * 0x94d049bb133111eb; x = z ^ (z >> 31); z = (x += 0x9e3779b97f4a7c15); z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; z = (z ^ (z >> 27)) * 0x94d049bb133111eb; _state1 = z ^ (z >> 31); _state2 = x; } } ulong Next() { ulong s0 = _state1; ulong s1 = _state2; ulong result = unchecked(BitOperations.RotateLeft(s0 + s1, 17) + s0); s1 ^= s0; _state1 = BitOperations.RotateLeft(s0, 49) ^ s1 ^ (s1 << 21); _state2 = BitOperations.RotateLeft(s1, 28); return result; } public int Next(int minValue, int maxValue) { if (minValue > maxValue) { throw new ArgumentOutOfRangeException(nameof(minValue)); } unchecked { long range = (long)maxValue - minValue; return (int)((uint)Next() * (1.0 / uint.MaxValue) * range) + minValue; } } public void NextBytes(Span buffer) { Span bufferUlong = MemoryMarshal.Cast(buffer); for (int i = 0; i < bufferUlong.Length; i++) { bufferUlong[i] = Next(); } for (int i = bufferUlong.Length * sizeof(ulong); i < buffer.Length; i++) { buffer[i] = unchecked((byte)Next()); } } }