mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-27 22:40:22 +00:00
4567bba03f
Removes TONS of unnecessary allocations, and is more simple
72 lines
No EOL
2 KiB
C#
72 lines
No EOL
2 KiB
C#
namespace PKHeX.Core
|
|
{
|
|
/// <summary>
|
|
/// Self-mutating value that returns a crypto value to be xor-ed with another (unaligned) byte stream.
|
|
/// <para>
|
|
/// This implementation allows for yielding crypto bytes on demand.
|
|
/// </para>
|
|
/// </summary>
|
|
[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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a <see cref="byte"/> from the current state.
|
|
/// </summary>
|
|
public uint Next()
|
|
{
|
|
var c = Counter;
|
|
var val = (Seed >> (c << 3)) & 0xFF;
|
|
if (c == 3)
|
|
{
|
|
XorshiftAdvance(ref Seed);
|
|
Counter = 0;
|
|
}
|
|
else
|
|
{
|
|
++Counter;
|
|
}
|
|
return val;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a <see cref="uint"/> from the current state.
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Count of bits set in value
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
} |