struct stable_random_state { unsigned shift: 32; unsigned carry: 8; unsigned current: 8; unsigned prev: 8; unsigned linear: 8; }; #define STABLE_RANDOM_NEXT_LINEAR(s) ((s) -> linear *= 73, (s) -> linear += 29, (s) -> linear) unsigned char stable_random (struct stable_random_state * state) { unsigned p; const unsigned char cycle_start_points[] = {1, 2, 4, 8, 13, 17, 23, 26, 29, 58, 0}; const unsigned char short_cycles[] = {0x72, 0x4f, 0x9f, 0x7b, 0x1a, 0x7b, 0x84, 0xe5, 0x56, 0x8d, 0xb0, 0x32, 0, 0, 1}; if (!state -> shift) for (p = 0; p < 4; p ++) state -> shift = (state -> shift << 8) | STABLE_RANDOM_NEXT_LINEAR(state); state -> shift ^= state -> shift >> 8; state -> shift ^= state -> shift << 9; state -> shift ^= state -> shift >> 23; if (state -> prev || state -> current) for (p = 0; p < (sizeof short_cycles - 3); p += 3) { if ((state -> prev == short_cycles[p]) && (state -> current == short_cycles[p + 1]) && (state -> carry == short_cycles[p + 2])) { state -> prev = short_cycles[p + 3]; state -> current = short_cycles[p + 4]; state -> carry = short_cycles[p + 5]; break; } } else for (p = 0; p < (sizeof cycle_start_points - 1); p ++) if (state -> carry == cycle_start_points[p]) { state -> carry = cycle_start_points[p + 1]; if (!state -> carry) { state -> prev = *short_cycles; state -> current = short_cycles[1]; state -> carry = short_cycles[2]; STABLE_RANDOM_NEXT_LINEAR(state); } break; } if (state -> carry >= 210) state -> carry -= 210; p = state -> carry + state -> prev + state -> current; if (!p || (p == 719)) { state -> prev = STABLE_RANDOM_NEXT_LINEAR(state); state -> carry = STABLE_RANDOM_NEXT_LINEAR(state); state -> current = STABLE_RANDOM_NEXT_LINEAR(state); if (state -> carry >= 210) state -> carry -= 210; } p = 210 * state -> prev + state -> carry; state -> prev = state -> current; state -> current = p & 0xff; state -> carry = p >> 8; STABLE_RANDOM_NEXT_LINEAR(state); p = state -> shift >> ((state -> linear >> 3) & 24); switch ((state -> linear >> 4) & 3) { case 0: return p + state -> current; case 1: return p ^ state -> current; case 2: return p - state -> current; default: return state -> current - p; } } void stable_random_initialize (struct stable_random_state * state, unsigned seed1, unsigned seed2, unsigned initial_mixing_count) { // assuming here that unsigned is 32-bit state -> shift = seed1; 1[(unsigned *) state] = seed2; while (initial_mixing_count --) stable_random(state); }