Is there a pseudo-random number generator simple enough to do in your head?

Viewed 40409

Are there are any pseudo-random number generators that are easy enough to do with mental arithmetic, or mental arithmetic plus counting on your fingers. Obviously this limits to fairly simple math - it needs to be something someone of average mathematical ability can do, or maybe average ability for a programmer, not a math prodigy.

The simplest I have found is the Middle square method, but not only is it known to be a poor source of randomness, it still looks too complex to do without pencil and paper.

If the only way to do this is by limiting the range, like maybe it only can output 8 bit numbers, that is fine. I suspect one of the standard PRNG algorithms would be simple enough in an 8 bit version, but I don't know enough to simplify any of them from the 32 bit version to an 8 bit version. (All the ones I looked at depend on specially picked seed numbers that are different depending how many bits you are working with, and usually only 32 and 64 bit examples are given.)

9 Answers

Here is a very simple one that is based on a linear method:

  1. Pick three number $a$, $b$, $n$ with $2<=a<n$ and $1<=b<n$ with $n$ being a prime. In this example, I'll use $a=83$, $b=52$, $n=101$.
  2. Let $f(x) = (ax+b) (mod n)$.
  3. Find the unique stationary point, which is the value $k$ such that $f(k)=k$. For the values of $a$, $b$, $n$ as above, the stationary point is $k=24$.
  4. Recursively apply $f$ starting with a seed that is not the stationary point. You get a stream that outputs values from $0$ to $n-1$ except $k$. When the value $n-1$ is generated, write it down as $k$ instead.

For this example, starting with 0, we get a stream of 0, 52, 25, 6, 45, 50, 61, 65, 94, 77, 80, 26, 89, 66, 76, 98, 5, 63, 29, 35, 28, 53, 7, 27, 71, 87, 1, 34, 46, 32, 82, 91, 30, 17, 49, 79, 44, 68, 40, 39, 57, 36, 10, 74, 33, 64, 11, 56, 54, 90, 48, 97, 23, 42, 3, 99, 88, 84, 55, 72, 69, 22, 60, 83, 73, 51, 43, 86, 19, 13, 20, 96, 41, 21, 78, 62, 47, 14, 2, 16, 67, 58, 18, 31, 24, 70, 4, 81, 8, 9, 92, 12, 38, 75, 15, 85, 37, 93, 95, 59, which has a period of 100. A period of $n-1$ is guaranteed if $a$ is a primitive root of $n$, so there are many pairs of $(a, b)$ that gives a period of $n-1$.

I recommend a set of 23 functions

X = 0 Definition_0ne(X); .... Definition_TwentyThree(X);

What each one does can be as simple as (X^2), but given 1 value all 23 most provide unique results.

From here you build a sequencer , that will call all 23 in a given order based off any seed, so if I gave you "Jimmy" as a seed for example. You could accept that and covert it to some form of decimal, then multiply it by some known non repeating decimal that goes out 23 decimal spots ( this value can be made up on the spot )

Then it will call the function closest to the last 2 decimal values, and Everytime it has already been called it will attempt to call the 2nd closest above, followed by 2nd closest below, after 23 passes, all remaining will be sequenced in , in a predertermined order , highest to lowest will work fine, stopping at the point that at least half of the functions have been called , and X is very much psuedo random, after all functions remaining are called the class will return the final X value

This takes a computer like .000000001 seconds to do, a human about 15 minutes on paper.

Your 23 functions could be as simple as X+1 , to X+23 , return X, you will never be able to accurately predict without first do the math of each function, then run on decimal modifier , then redoing the math , over and over to find out which functions will get called , and what order the would get called in, and only the author would know this, given that 12 of the 23 of the functions will get called minimally, and 23 max , you shouldn't ever have to worry about anyone backwards engineering your code :)

Sure they can keep putting in the same seed, but that won't solve anything and in a game or application setting your seed will be amended with a piece of extra info generated from storage in most cases. I like to use touch sequences on Mobile for that extra data, is your last 3 initial contact points are always saved and added to what ever random seed you start with , on a computer if it's an application I used a pointer to some kind of memory that only gets allocated after the initiation of the application, and i don't know what to use html , but I am sure there is a way to get information that isnt random but isn't the same in every instance to amend to the seed, to make backward engineering much more difficult

Related