Tests Used By This Study



Overview

The quality of pseudo random number generators varies widely. Some are barely able to create more than a dozen unique numbers, while others can go on for ages without falling into repeating patterns.

There are a number of ways to check the quality of random number generators, the most famous of which are the Diehard tests.

However, these tests can only look at the output of a generator and guess if it is random. Because this study uses custom implementations of the different pseudo random number generators, it's possible for the testing suite to directly access the internal state of the generator and make observations that most randomness tests cannot.

To take advantage of this, four tests have been created to gauge the effectiveness and randomness of any generator being examined.




Seeds

Pseudo random number generators are initialized using a seed value. To perform this battery of tests, six predetermined seed values are used for each test.

These values, in order, are as follows:
SEEDNOTES
1138The famous number used as an easter egg by Lucasfilm.
65535The largest value that can be stored in an unsigned 16-bit integer.
8675309Jenny's phone number, from the song by Tommy Tutone.
16777216The number of colors possible using True Color (24-bit) graphics.
123456789A nine digit number created by counting from 1 to 9.



Test 1: Period Length

A random number generator's period is the number of results that can be generated before the generator either repeats itself or falls into a loop. Both conditions restrict how random the generator can be.

This test is performed by initialing the generator with the given seed, then drawing 80,000 results. After each result, the generator's internal state is checked and if the current state is a repeat of a previous one, the test ends.

The generator is considered to have passed this test if there was no repeated state during the 80,000 queries. Note that many generators will be able to pass this test even if their output is not that random - all that matters is their internal state is always unique.

Test 2: Dice Rolling

This test attempts to see if the results from the generator are skewed in some way by using the generator's output to roll virtual dice. In theory, there should be a roughly equal chance of getting each number on a 6-sided dice. In practice, the output tends to favor specific outcomes.

This test is performed by initialing the generator with the given seed, then drawing a result as a floating point number (obtained by dividing the output by the generator's maximum possible result). This number is then compared to six ranges (eg, a number between 0.32 and 0.48 is considered to be a 2 ). A counter keeps track of how many results fall into each range. This is then done 10000 times for each seed and the results tallied. Finally, a graph of the overall percentages is rendered.

The generator is considered to have passed this test if there is a roughly even spread between the ranges (around 16% per outcome; shown as a red line on the chart).

Test 3: Dart Throwing

This is a variation on the classic Parking Lot test. Virtual darts are "thrown" at a dart board. Each dart is represented by an X,Y coordinate pair, while the dart board is simply an area of 100x100 possible spaces.

This test is performed by initialing the generator with the given seed. Next, 12,000 darts are thrown at the dartboard. To do this, each dart is created by generating two random floating point numbers and multiplying them against 100 to get the dart's target coordinates. The distance formula is used to check if there is already a dart in this approximate location. If so, the throw "misses" and the new dart is discarded. If not, the throw "lands" and the new dart is added to the list of darts on the dartboard.

The generator is considered to have passed this test if at least 6,000 darts managed to hit the dartboard.

Test 4: Crush Test

This test uses the famous zlib library to locate sections of redundant output from a random number generator. In other words, a file is produced and then "zipped". Since the compression algorithm uses redundancy and repetition to reduce the target file's size, this can be used to quickly observe how random the output of a pseudo random number generator really is.

This test is performed by initialing the generator with the given seed and writing 10000 results to a file. Since many generators cannot produce a full 64-bit integer as output, only the least significant byte is stored. This file is then compressed using zlib. The size of the original file is then compared with the size of the compressed file and expressed as a percentage.

The generator is considered to have passed this test if the compressed file at least 70% as large as the original. Some generators are random enough that the compressed file is actually larger than the original, which means there wasn't enough redundant data for compression to work properly.

Test 5: Plot Test

This test attempts to visualize how random the output of the generator is by plotting 32768 points in a 256x256 field.

This test is performed by initialing the generator using Jenny's number as the seed, then creating a 256x256 pixel image filled with white. Using the least significant byte, 32768 X,Y coordinates are generated and mapped to the image. Each time a point is marked, the color value is decremented by 50. This allows us to clearly see when a point is repeated multiple times - the darker the pixel, the more times it appeared in the sample.

The generator is considered to have passed this test if the resulting image resembles static. The generator fails this test if there are repeating patterns, few unique points, or if the points create a striped image.

Test 6: Example Output

After the other five tests are completed, the generator is reinitialized using Jenny's number as the seed and 400 results are drawn.

This is not a test per se; its purpose is to allow readers to see a sampling of the generator's possible output.



A WFTID Website