Consider the prime 3. To fully express all possible outputs, think of it this way...
bias + step mod prime
The bias
is just an offset bias. step
is an accumulator (if it's 1
for example, it would just be 0, 1, 2
in sequence, while 2
would result in 0, 2, 4
) and prime
is the prime number we want to generate the permutations against.
For example. A simple sequence of 0, 1, 2
would be...
0 + 0 mod 3 = 0
0 + 1 mod 3 = 1
0 + 2 mod 3 = 2
Modifying a couple of those variables for a second, we'll take bias
of 1
and step
of 2
(just for illustration)...
1 + 2 mod 3 = 0
1 + 4 mod 3 = 2
1 + 6 mod 3 = 1
You'll note that we produced an entirely different sequence. No number within the set repeats itself and all numbers are represented (it's bijective). Each unique combination of offset and bias will result in one of prime!
possible permutations of the set. In the case of a prime
of 3
you'll see that there are 6
different possible permuations:
0,1,2
0,2,1
1,0,2
1,2,0
2,0,1
2,1,0
If you do the math on the variables above you'll not that it results in the same information requirements...
1/3! = 1/6 = 1.66..
... vs...
1/3 (bias) * 1/2 (step) => 1/6 = 1.66..
Restrictions are simple, bias
must be within 0..P-1
and step
must be within 1..P-1
(I have been functionally just been using 0..P-2
and adding 1
on arithmetic in my own work). Other than that, it works with all prime numbers no matter how large and will permutate all possible unique sets of them without the need for memory beyond a couple of integers (each technically requiring slightly less bits than the prime itself).
Note carefully that this generator is not meant to be used to generate sets that are not prime in number. It's entirely possible to do so, but not recommended for security sensitive purposes as it would introduce a timing attack.
That said, if you would like to use this method to generate a set sequence that is not a prime, you have two choices.
First (and the simplest/cheapest), pick the prime number just larger than the set size you're looking for and have your generator simply discard anything that doesn't belong. Once more, danger, this is a very bad idea if this is a security sensitive application.
Second (by far the most complicated and costly), you can recognize that all numbers are composed of prime numbers and create multiple generators that then produce a product for each element in the set. In other words, an n
of 6
would involve all possible prime generators that could match 6
(in this case, 2
and 3
), multiplied in sequence. This is both expensive (although mathematically more elegant) as well as also introducing a timing attack so it's even less recommended.
Lastly, if you need a generator for bias
and or step
... why don't you use another of the same family :). Suddenly you're extremely close to creating true simple-random-samples (which is not easy usually).
N
is prime. I'm very hesitant to post it (as I'm still working on a CSRNG based on the concept) but will do so as an answer but if you're still interested (and the conditions described above match) I'd be willing. – AlcotN
is prime. Not if you're looking to brute force something between two primes. In other words, it's not a solution to help you find permutations of any set, only unique sets that are prime in count. (Hence, if-and-only-if.) – Alcot