namespace PKHeX.Core { /// /// Self-mutating value that returns a crypto value to be xor-ed with another (unaligned) byte stream. /// /// This implementation allows for yielding crypto bytes on demand. /// /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "Unused")] public struct SCXorShift32 { private int Counter; private uint Seed; public SCXorShift32(uint seed) { var pop_count = PopCount(seed); for (var i = 0; i < pop_count; i++) XorshiftAdvance(ref seed); Counter = 0; Seed = seed; } /// /// Gets a from the current state. /// public uint Next() { var c = Counter; var val = (Seed >> (c << 3)) & 0xFF; if (c == 3) { XorshiftAdvance(ref Seed); Counter = 0; } else { ++Counter; } return val; } /// /// Gets a from the current state. /// public uint Next32() { return Next() | (Next() << 8) | (Next() << 16) | (Next() << 24); } private static void XorshiftAdvance(ref uint key) { key ^= key << 2; key ^= key >> 15; key ^= key << 13; } /// /// Count of bits set in value /// private static uint PopCount(uint x) { x -= ((x >> 1) & 0x55555555u); x = (x & 0x33333333u) + ((x >> 2) & 0x33333333u); x = (x + (x >> 4)) & 0x0F0F0F0Fu; x += (x >> 8); x += (x >> 16); return x & 0x0000003Fu; } } }