Reseeding implementation and commentary needed
After seeding, it can take many iterations for the apparent effect of the seed to "warm up", and seed values that are close will be seen to fail to diverge much when compared at equal numbers of steps.
This correlation was discovered when trying to use the LFSR as a hash of a 2D X/Y to a random value. Patterns show up easily when plotting 16-bit X<<8 + Y seeds, and can't really be eradicated just by iterating the LFSR.
After investigating for a while, I came up with a method of ticking it once for each bit in the LFSR, but swapping the bytes whenever the middle bit was set.
16-bit python method:
def galois16(s,t):
for i in range(t):
f = s & 0x8000
s = (s << 1) & 0xFFFF
if f: s ^= 0x0039
return s
def swap16(s):
return ((s << 8) | (s >> 8)) & 0xFFFF
def randxy(x,y):
x = x & 0xFF
y = y & 0xFF
s = (x << 8) | y
for i in range(16):
if (s & 0x80):
s = swap16(s)
s = galois16(s,1)
return s & 0xFF
32-bit python method.
def galois32(s,t):
for i in range(t):
f = s & 0x80000000
s = (s << 1) & 0xFFFFFFFF
if f: s ^= 0x000000C5
return s
def swap32(s):
return \
(((s >> 0) & 0xFF) << 16) | \
(((s >> 8) & 0xFF) << 24) | \
(((s >> 16) & 0xFF) << 0) | \
(((s >> 24) & 0xFF) << 8)
def randxy(x,y):
x = x & 0xFF
y = y & 0xFF
s = (x << 24) | (y << 16) | (x << 8) | (y << 0)
for i in range(32):
if (s & 0x8000):
s = swap32(s)
s = galois32(s,1)
return s & 0xFF
A method for the 24-bit one must also be devised and tested. (The byte swapping configuration matters, so the solution might not be obvious.) Also, should put an | 1 on the seed setup so that X=0/Y=0 doesn't make a dead seed.
Probably want to place the low byte of seed in the middle byte to trigger the swap quickly.
Need to create 6502 implementations of the above, and also add documentation about this need, since this inefficiency of seed setup is important for the user to know.