'hamster_nz', indeed you are correct on the polynomials. Also I'd like to thank your interest on my question as I'm struggling with your algorithm. Your code uses several 'magic' values that I don't quite get their origins but they do seem to be (or at least they are equal to):
0x0c == fourth state after 00000
0x19 == fourth state after 00001
0x07 == fourth state after 00010
0x0e == fourth state after 00100
0x09 == fourth state after 01000
0x06 == fourth state after 10000
If I'm correct your code is very efficient at computing the state at a fixed offset from any initial state, requiring only six 'magic' values. But I need to be able to compute the state at any offset from a fixed initial state (given the periodic nature of the LFSR, as you already mentioned, that initial state can be 0 and the offset can be reversed). From your code and explanation the first 'magic' value alone would require a table with one element for each possible offset, totally negating the purpose of the algorithm. So, can you clarify the origin of those 'magic' numbers ?
I did leave enough breadcrumbs

I got those numbers exactly as you suggested - I put 00 as the initial state of the LFSR, and ran it forward four states, giving 0C.
I then put 01 ran it forward four states, giving 19. To isolate the change that bit makes, I have to remove the change that would occur even if this bit wasn't set, hence why it is XORed with 0C
I then did the same for 02, 04, 08 & 10, so I know what effect that having each bit set leads to four cycles into the future.
There isn't anything magical about the number four, I just wanted something I could count lines on the screen.
So what if I want to jump ahead 8 states? Easy - just run it through it twice.
guess = 0x0c;
if((state & 0x01) != 0) guess ^= 0x19 ^ 0x0C;
if((state & 0x02) != 0) guess ^= 0x07 ^ 0x0C;
if((state & 0x04) != 0) guess ^= 0x0e ^ 0x0C;
if((state & 0x08) != 0) guess ^= 0x09 ^ 0x0C;
if((state & 0x10) != 0) guess ^= 0x06 ^ 0x0C
// advance the state four cycles into the future
state = guess;
guess = 0x0c;
if((state & 0x01) != 0) guess ^= 0x19 ^ 0x0C;
if((state & 0x02) != 0) guess ^= 0x07 ^ 0x0C;
if((state & 0x04) != 0) guess ^= 0x0e ^ 0x0C;
if((state & 0x08) != 0) guess ^= 0x09 ^ 0x0C;
if((state & 0x10) != 0) guess ^= 0x06 ^ 0x0C
state = guess;
// statue is now 8 cycles into the future
Now If I run 00, 01, 02, 04, 08 and 10, through this "Advance 8 cycles" I will end up with 6 new magic numbers, that can be used to jump 8 states ahead in one operation.
You can probably see where this is going...
If you build a table "magic[5][6]" where:
* magic[0][] is what is used to jump ahead one state
* magic[1][] is what is used to jump ahead two states
* magic[2][] is what is used to jump ahead four states
* magic[3][] is what is used to jump ahead eight states
* magic[4][] is what is used to jump ahead sixteen states
You can calculate the value in magic[1][] by using the values in magic[0] twice. You can then calculate the value in magic[2][] by using calculate the value in magic[1][] twice, and so on. (For debugging the values for magic[2][] should be the numbers we already have)
So we now have a way to skip forward any of 1,2,4, 8 or 16 states.
If we want to skip back 10 states because the LFSR has 31 states is the same as skipping forward 21 states. You can use magic[0][], magic[2][] and magic[4][], to jump forward 1, then 4, then 16 states, for a total of 21, but only performing three sets of calculations:
So the end code looks something like:
for(index = 0; index < lfsr_bit_length; index++) {
if((number_to_skip & (1<<index)) != 0) {
guess = magic[index][0];
if((state & 0x01) != 0) guess ^= magic[index][1] ^ magic[bit][0];
if((state & 0x02) != 0) guess ^= magic[index][2] ^ magic[bit][0];
if((state & 0x04) != 0) guess ^= magic[index][3] ^ magic[bit][0];
if((state & 0x08) != 0) guess ^= magic[index][4] ^ magic[bit][0];
if((state & 0x10) != 0) guess ^= magic[index][5] ^ magic[bit][0];
state = guess;
}
}
For a small LFSR like this it doesn't help much, but for a 36 bit FSM it is far quicker that rolling through states.
In BigO notation it changes the runtime from O(2^n) to O(n^2).