I need some good pseudo random number generator that can be computed like a pure function from its previous output without any state hiding. Under "good" I mean:
I must be able to parametrize generator in such way that running it for 2^n
iterations with any parameters (or with some large subset of them) should cover all or almost all values between 0
and 2^n - 1
, where n
is the number of bits in output value.
Combined generator output of n + p
bits must cover all or almost all values between 0
and 2^(n + p) - 1
if I run it for 2^n
iterations for every possible combination of its parameters, where p
is the number of bits in parameters.
For example, LCG can be computed like a pure function and it can meet first condition, but it can not meet second one. Say, we have 32-bit LCG, m = 2^32
and it is constant, our p = 64
(two 32-bit parameters a
and c
), n + p = 96
, so we must peek data by three ints from output to meet second condition. Unfortunately, condition can not be meet because of strictly alternating sequence of odd and even ints in output. To overcome this, hidden state must be introduced, but that makes function not pure and breaks first condition (long hidden period).
EDIT: Strictly speaking, I want family of functions parametrized by p
bits and with full state of n
bits, each generating all possible binary strings of p + n
bits in unique "randomish" way, not just continuously incrementing (p + n)
-bit int. Parametrization required to select that unique way.
Am I wanting too much?
The PRNG should be very fast. The application should spend its time running the actual algorithms, not generating random numbers. PRNG output should have robust statistical qualities. Bits should appear to be independent and the output should closely follow the desired distribution.
A PRNG is said to be cryptographically secure if, assuming that it operates over a wide enough unknown n-bit key, its output is computationally indistinguishable from uniformly random bits. In the 90's, a popular choice was RC4, which is very simple to implement, and quite fast.
Rand provides some convenient generators in the rngs module. Often you can just use thread_rng , a function which automatically initializes an RNG in thread-local memory and returns a reference to it. It is fast, good quality, and (to the best of our knowledge) cryptographically secure.
Surprisingly, the general-purpose random number generators that are in most widespread use are easily predicted. (In contrast RNGs used to construct stream ciphers for secure communication are believed to be infeasible to predict, and are known as cryptographically secure).
You can use any block cipher, with a fixed key. To generate the next number, decrypt the current one, increment it, and re-encrypt it. Because block ciphers are 1:1, they'll necessarily iterate through every number in the output domain before repeating.
Try LFSR
All you need is list of primitive polynomials.
Period of generating finite field this way, generates field of size 2^n-1. But you can generalise this procedure to generate anything whit period of k^n-1.
I have not seen this implemented, but all you have to implement is shifting numbers by small number s>n where gcd(s,2^n-1) == 1. gcd stands for greatest common divisor
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With