Reversible pseudo-random sequence generator

I asked a very similar question at the tigsource forums.

Hashing

At least in games, a hash function could probably do what you want. You could do it like this

class ReversibleRNG {
    int x;
public:
    ReversibleRNG(int seed) : x(seed) {}
    int next(){return yourFavoriteHash(++x);}
    int prev(){return yourFavoriteHash(--x);}
};

Reversible linear congruential generator (lcg)

As multiple people have pointed out, an lcg is indeed reversible. In an lcg, the next state is computed like this:

x = (a * prevx + c) mod m

We can reorder this:

x ≡ a * prevx + c (mod m)
x - c ≡ a * prevx (mod m)

Since a and m are chosen to be relatively prime in an lcg, we can find the inverse by using the extended euclid’s algorithm.

ainverse = extEuclid(a, m).x;
ainverse * (x - c) ≡ ainverse * a * prevx (mod m)
ainverse * (x - c) ≡ prevx (mod m)

Which means

prevx = ainverse * (x - c) mod m

If you choose m and a carefully, the algorithm can have a period of 2^64

Implementation

I did a header-only implementation of this algorithm in case anyone’s interested.

Leave a Comment