Random Number Generator Recommendations for Applications
Begun on Mar. 5, 2016; last updated on July 31, 2017.
Most apps that use random numbers care about either unpredictability or speed/high quality.
Introduction and Summary
As I see it, there are two kinds of random number generators (RNGs) needed by most applications, namely—
 statisticalrandom generators, which seek to generate numbers that follow a uniform random distribution, and
 unpredictablerandom generators, which seek to generate numbers that are costprohibitive to predict.
This page will discuss these two kinds of RNG, and make recommendations on their use and properties.
In addition, other applications require numbers that "seem" random but are based on an initial state, or "seed". This page will discuss when applications should specify their own seeds.
Then, this page will explain what programming language APIs implement statisticalrandom and unpredictablerandom generators and give advice on implementing them in programming languages.
Finally, this page will discuss issues on shuffling with an RNG.
Summary
The following table summarizes the kinds of RNGs covered in this document.
Kind of RNG  When to Use This RNG  Examples 

UnpredictableRandom  In computer/information security cases, or when speed is not a concern.  /dev/urandom , CryptGenRandom 
StatisticalRandom  When computer/information security is not a concern, but speed is. See also "Shuffling".  xoroshiro128+ , xorshift128+ 
Seeded PRNG  When generating reproducible results in a way not practical otherwise.  Statisticalrandom quality PRNG with custom seed 
Contents
 Introduction and Summary
 Contents
 Definitions
 UnpredictableRandom Generators
 StatisticalRandom Generators
 Seeded Random Generators
 Programming Language APIs
 Advice for New Programming Language APIs
 Shuffling
 Motivation
 Conclusion
 Notes
 License
Definitions
The following definitions are helpful in better understanding this document.
 Random number generator (RNG). A number generator that outputs numbers that seem to occur by chance. (In this document, RNGs are limited to those that seek to generate random numbers that are approximately uniformly distributed.)
 Pseudorandom number generator (PRNG). A number generator that outputs seemingly random numbers using a deterministic algorithm, that is, an algorithm that returns the same output for the same input and state every time. (In this document, RNGs include PRNGs.)
 Seed. Arbitrary data for initializing the state of a PRNG.
 State length. The maximum size of the seed a PRNG can take to initialize its state without truncating or compressing that seed.
 Period. The maximum number of values in a generated sequence for a PRNG before that sequence repeats. The period will not be greater than 2^{L} where
L
is the PRNG's state length.
UnpredictableRandom Generators
Unpredictablerandom implementations (also known as "cryptographically strong" or "cryptographically secure" RNGs) seek to generate random numbers that are costprohibitive to predict. Such implementations are indispensable in computer security and information security contexts, such as—
 generating keying material, such as encryption keys,
 generating random passwords, nonces, or session identifiers,
 generating "salts" to vary cryptographic hashes of the same password,
 use in communications between two networked computers,
 use in transfer, transport, messaging, and other communication protocols, and
 cases (such as in multiplayer networked games) when predicting future random numbers would give a player or user a significant and unfair advantage.
They are also useful in cases where the application generates random numbers so infrequently that the RNG's speed is not a concern.
An unpredictablerandom implementation ultimately relies on one or more nondeterministic sources (sources that don't always return the same output for the same input) for random number generation. Sources that are reasonably fast for most applications (for instance, by producing very many random bits per second), especially sources implemented in hardware, are highly advantageous here, since an implementation for which such sources are available can rely less on PRNGs, which are deterministic and benefit from reseeding as explained later.
Quality
An unpredictablerandom implementation generates uniformly distributed random bits such that it would be costprohibitive for an outside party to guess either prior or future unseen bits of the random sequence correctly with more than a 50% chance per bit, even with knowledge of the randomnessgenerating procedure, the implementation's internal state at the given point in time, and/or extremely many outputs of the RNG. (If the sequence was generated directly by a PRNG, ensuring future bits are unguessable this way should be done wherever the implementation finds it feasible; see "Seeding and Reseeding".)
Seeding and Reseeding
If an unpredictablerandom implementation uses a PRNG, the following requirements apply.
The PRNG's state length must be at least 128 bits and should be at least 256 bits.
Before an instance of the RNG generates a random number, it must have been initialized ("seeded") with an unpredictable seed, defined as follows. The seed—
 must consist of data which meets the quality requirement described earlier, which does not contain, in whole or in part, the PRNG's own output, and which ultimately derives from one or more nondeterministic sources (such data may be mixed with other arbitrary data as long as the result is no less costprohibitive to predict), and
 must be at least the same size as the PRNG's state length.
The RNG should be reseeded from time to time (using a newly generated unpredictable seed) to help ensure the unguessability of the output. If the implementation reseeds, it must do so before it generates more than 2^{67} bits without reseeding and should do so before it generates more than 2^{32} bits without reseeding.
Examples
Examples of unpredictablerandom implementations include the following:
 The
/dev/random
device on many Unixbased operating systems, which generally uses only nondeterministic sources; however, in some implementations of the device it can block for seconds at a time, especially if not enough randomness ("entropy") is available.  The
/dev/urandom
device on many Unixbased operating systems, which often relies on both a PRNG and the same nondeterministic sources used by/dev/random
.  The
CryptGenRandom
method on Windows.  Cryptographic hash functions that take very hardtopredict signals as input, preferably from more than one nondeterministic source. Such sources include, where available—
 disk access timings,
 keystroke timings,
 thermal noise, and
 A. Seznec's technique called hardware volatile entropy gathering and expansion, provided a highresolution counter is available.
StatisticalRandom Generators
Statisticalrandom generators are used, for example, in simulations, numerical integration, and many games to bring an element of chance and variation to the application, with the goal that each possible outcome is equally likely. However, statisticalrandom generators are generally suitable only if—
 computer security and information security are not involved, and
 the application generates random numbers so frequently that it would slow down undesirably if an unpredictablerandom implementation were used instead.
If more than 20 items are being shuffled, a concerned application would be well advised to use alternatives to this kind of implementation (see "Shuffling").
A statisticalrandom implementation is usually implemented with a PRNG, but can also be implemented in a similar way as an unpredictablerandom implementation provided it remains reasonably fast.
Quality
A statisticalrandom implementation generates random bits, each of which is uniformly randomly distributed independently of the other bits, at least for nearly all practical purposes. The implementation must be highly likely to pass all the tests used in TestU01
's Crush
, SmallCrush
, and BigCrush
test batteries [L'Ecuyer and Simard 2007], and ought to be highly likely to pass other known statistical randomness tests. The RNG need not be equidistributed. (Mentioning specific test batteries here is in the interest of precision and makes it clearer whether a particular RNG meets these quality requirements.)
Seeding and Reseeding
If statisticalrandom implementation uses a PRNG, the following requirements apply.
The PRNG's state length must be at least 64 bits, should be at least 128 bits, and is encouraged to be as high as the implementation can go to remain reasonably fast for most applications.
Before an instance of the RNG generates a random number, it must have been initialized ("seeded") with a seed described as follows. The seed—
 must consist of data not known a priori by the implementation, such as random bits from an unpredictablerandom implementation,
 must not be a fixed value or a userentered value,
 should not be trivially predictable in any of its bits, as far as practical,
 is encouraged not to consist of a timestamp (especially not a timestamp with millisecond or coarser granularity)^{(1)}, and
 must be at least the same size as the PRNG's state length.
The implementation is encouraged to reseed itself from time to time (using a newly generated seed as described earlier), especially if the PRNG has a state length less than 238 bits. If the implementation reseeds, it should do so before it generates more values than the square root of the PRNG's period without reseeding.
Examples and NonExamples
Examples of statisticallyrandom generators include the following:
xoroshiro128+
(state length 128 bits; nonzero seed — but see warning in the source code about the lowest bit of the PRNG's outputs).xorshift128+
(state length 128 bits; nonzero seed).Lehmer128
(state length 128 bits).JKISS
on top of page 3 of Jones 2010 (state length 128 bits; seed with four 32bit nonzero pieces). C++'s
std::ranlux48
engine (state length 577 bits; nonzero seed).
Nonexamples include the following:
 Mersenne Twister shows a systematic failure in one of the
BigCrush
tests. (See also S. Vigna, "An experimental exploration of Marsaglia'sxorshift
generators, scrambled", as published in thexoroshiro128+
website.)  Any linear congruential generator with modulus 2^{63} or less (such as
java.util.Random
and C++'sstd::minstd_rand
andstd::minstd_rand0
engines) has a state length of less than 64 bits. (See also the Wikipedia article for further problems with linear congruential generators.)
Seeded Random Generators
In addition, some applications use pseudorandom number generators (PRNGs) to generate results based on apparentlyrandom principles, starting from a known initial state, or "seed". Such applications usually care about reproducible results. (Note that in the definitions for unpredictablerandom and statisticalrandom generators given earlier, the PRNGs involved are automatically seeded before use.)
Seeding Recommendations
An application should use a PRNG with a seed it specifies (rather than an automaticallyinitialized PRNG or another kind of RNG) only if—
 the initial state (the seed) which the "random" result will be generated from—
 is hardcoded,
 was entered by the user,
 is known to the application and was generated using a statisticalrandom or unpredictablerandom implementation (as defined earlier),
 is a verifiable random number (as defined later), or
 is based on a timestamp (but only if the reproducible result is not intended to vary during the time specified on the timestamp and within the timestamp's granularity; for example, a year/month/day timestamp for a result that varies only daily),
 the application might need to generate the same "random" result multiple times,
 the application either—
 makes the seed (or a "code" or "password" based on the seed) accessible to the user, or
 finds it impractical to store or distribute the "random" results or the random numbers (rather than the seed) for later use, such as—
 by saving the result to a file,
 by storing the random numbers for the feature generating the result to "replay" later, or
 by distributing the results or the random numbers to networked users as they are generated,
 the random number generation method will remain stable for as long as the relevant feature is still in use by the application, and
 any feature using that random number generation method to generate that "random" result will remain backward compatible with respect to the "random" results it generates, for as long as that feature is still in use by the application.
As used here, a random number generation method is stable if it uses a deterministic algorithm, outputs the same random sequence given the same seed, and has no randomnumber generation behavior that is unspecified, that is implementationdependent, or that may change in the future. For example—
java.util.Random
is stable, the C
rand
method is not stable (because the algorithm it uses is unspecified),  C++'s random number distribution classes, such as
std::uniform_int_distribution
, are not stable (because the algorithms they use are implementationdefined according to the specification), and  .NET's
System.Random
is not stable (because its generation behavior may change in the future).
Seedable PRNG Recommendations
Which PRNG to use for generating reproducible results depends on the application. But as recommendations, any PRNG algorithm selected for producing reproducible results—
 should meet or exceed the quality requirements of a statisticalrandom implementation,
 should be reasonably fast, and
 should have a state length of 64 bits or greater.
Examples
Custom seeds can come into play in the following situations, among others.
Games
Many kinds of games generate game content using apparentlyrandom principles, such as—
 procedurally generated maps for a roleplaying game,
 shuffling a digital deck of cards for a solitaire game, or
 a game board or puzzle board that normally varies every session,
where the game might need to generate the same content of that kind multiple times.
In general, such a game should use a PRNG with a custom seed for such purposes only if—
 generating the random content uses relatively many random numbers (say, more than a few thousand), and the application finds it impractical to store or distribute the content or the numbers for later use (see recommendations 2 and 3), or
 the game makes the seed (or a "code" or "password" based on the seed, such as a barcode or a string of letters and digits) accessible to the player, to allow the player to generate the level or state repeatedly (see recommendations 2 and 3).
Option 1 often applies to games that generate procedural terrain for game levels, since the terrain often exhibits random variations over an extended space. Option 1 is less suitable for puzzle game boards or card shuffling, since much less data needs to be stored.
Unit Testing
A custom seed is appropriate when unit testing a method that uses a seeded PRNG in place of another kind of RNG for the purpose of the test (provided the method meets recommendation 5).
Verifiable Random Numbers
Verifiable random numbers are random numbers (such as seeds for PRNGs) that are disclosed along with all the information required to verify their generation. Usually, of the information used to derive such numbers, at least some of it is not known by anyone until some time after the announcement is made that those numbers will be generated, but all of it will eventually be publicly available. In some cases, some of the information required to verify the numbers' generation is disclosed in the announcement that those numbers will be generated.
One process to generate verifiable random numbers is described in RFC 3797 (to the extent its advice is not specific to the Internet Engineering Task Force or its Nominations Committee). Although the source code given in that RFC uses the MD5 algorithm, the process does not preclude the use of hash algorithms stronger than MD5 (see the last paragraph of section 3.3 of that RFC).
Noise
Randomly generated numbers can serve as noise, that is, a randomized variation in images and sound. (See also Red Blob Games, "Noise Functions and Map Generation").
If the noise implementation implements cellular noise, value noise, or gradient noise (such as Perlin noise), then different considerations apply depending on the implementation:
 If the implementation uses an RNG to initialize a table of gradients or hash values in advance, to be used later by the noise function (a function that outputs seemingly random numbers given an ndimensional point), then the same RNG recommendations apply to the implementation as they do to most other cases. This kind of approach is recommended wherever feasible, especially where computer and information security are involved in the noise generation.
 A noise implementation that uses a table of pregenerated gradients or hash values should be used only if the seeding recommendations apply to the noise generation (treating the implementation as using a "hardcoded" seed).
 If the noise function incorporates a hash function (including a PRNG that takes the input as a seed and outputs a random number^{(3)})—
 that hash function should—
 be reasonably fast,
 be stable (as defined in "Seeding Recommendations"), and
 be designed such that every bit of the input affects every bit of the output without a clear preference for 0 or 1 (the socalled "avalanche" property), and
 the noise implementation should be initialized in advance with arbitrary data of fixed length to provide to the hash function as part of its input, if the seeding recommendations apply to the noise generation.
 that hash function should—
The fractional Brownian motion technique combines several layers of cellular, value, or gradient noise by calling the underlying noise function several times. The same considerations apply to fractional Brownian motion as they do to the underlying noise implementation.
If the noise implementation implements other kinds of noise, such as white noise, pink noise, or other colored noise^{(2)}, then the same RNG recommendations apply to the implementation as they do to most other cases.
Programming Language APIs
The following table lists techniques, methods, and functions that implement unpredictablerandom and statisticalrandom RNGs for popular programming languages. Note the following:
 In singlethreaded applications, for each kind of RNG, it's encouraged to create a single instance of the RNG on application startup and use that instance throughout the application.
 In multithreaded applications, for each kind of RNG, it's encouraged to either—
 create a single threadsafe instance of the RNG on application startup and use that instance throughout the application, or
 store separate and independentlyinitialized instances of the RNG in threadlocal storage, so that each thread accesses a different instance (this may not always be ideal for unpredictablerandom RNGs).
 Methods and libraries mentioned in the "Statisticalrandom" column need to be initialized with a fulllength seed before use (for example, a seed generated using an implementation in the "Unpredictablerandom" column).
 The mention of a thirdparty library in this section does not imply sponsorship or endorsement of that library, or imply a preference of that library over others. The list is not comprehensive.
Language  Unpredictablerandom  Statisticalrandom  Other 

C/C++ (G)  (C)  xoroshiro128plus.c (128bit nonzero seed); xorshift128plus.c (128bit nonzero seed) 

Python  secrets.SystemRandom (since Python 3.6); os.urandom() 
ihaque/xorshift library (128bit nonzero seed; default seed uses os.urandom() ) 
random.getrandbits() (A); random.seed() (19,936bit seed) (A) 
Java (D)  (C); java.security.SecureRandom (F) 
grunka/xorshift (XORShift1024Star or XORShift128Plus ) 

JavaScript  crypto.randomBytes(byteCount) (node.js only) 
xorshift library 
Math.random() (floatingpoint) (B) 
Ruby  (C); SecureRandom class (require 'securerandom' ) 
Random#rand() (floatingpoint) (A) (E); Random#rand(N) (integer) (A) (E); Random.new(seed) (default seed uses entropy) 
(A) Default general RNG implements the Mersenne Twister, which doesn't meet the statisticalrandom requirements, strictly speaking, but may be adequate for many applications due to its extremely long period.
(B) JavaScript's Math.random
is implemented using xorshift128+
in the latest V8 engine, Firefox, and certain other modern browsers at the time of writing; the exact algorithm to be used by JavaScript's Math.random
is "implementationdependent", though, according to the ECMAScript specification.
(C) See "Advice for New Programming Language APIs" for implementation notes for unpredictablerandom implementations.
(D) Java's java.util.Random
class uses a 48bit seed, so doesn't meet the statisticalrandom requirements. However, a subclass of java.util.Random
might be implemented to meet those requirements.
(E) In my opinion, Ruby's Random#rand
method presents a beautiful and simple API for random number generation.
(F) At least in Unixbased systems, calling the SecureRandom
constructor that takes a byte array is recommended. The byte array should be data described in note (C).
(G) std::random_device
, introduced in C++11, is not recommended because its specification leaves considerably much to be desired. For example, std::random_device
can fall back to a pseudorandom number generator of unspecified quality without much warning.
Advice for New Programming Language APIs
Wherever possible, existing libraries or techniques that already meet the requirements for unpredictablerandom and statisticalrandom RNGs should be used. For example—
an unpredictablerandom implementation can—
 read from the
/dev/urandom
and/or/dev/random
devices in most Unixbased systems (using theopen
andread
system calls where available),  call the
getentropy
method on OpenBSD, or  call the
CryptGenRandom
API in Windowsbased systems,
and only use other techniques if the existing solutions are inadequate in certain respects or in certain circumstances, and
 read from the
 a statisticalrandom implementation can use a PRNG algorithm mentioned as an example in the statisticalrandom generator section.
If existing solutions are inadequate, a programming language API could implement unpredictablerandom and statisticalrandom RNGs by filling an output byte buffer with random bytes, where each bit in each byte will be randomly set to 0 or 1. For instance, a C language API for unpredictablerandom generators could look like the following: int random(uint8_t[] bytes, size_t size);
, where "bytes" is a pointer to a byte array, and "size" is the number of random bytes to generate, and where 0 is returned if the method succeeds and nonzero otherwise. Any programming language API that implements such RNGs by filling a byte buffer must run in amortized linear time on the number of random bytes the API will generate.
Unpredictablerandom and statisticalrandom implementations—
 should be reasonably fast for most applications, and
 should be safe for concurrent use by multiple threads, whenever convenient.
My document on random number generation methods includes details on eleven uniform random number methods; in my opinion, a new programming language's standard library should include those eleven methods separately for unpredictablerandom generators and for statistical RNGs. That document also discusses how to implement other methods to generate random numbers or integers that follow a given distribution (such as a normal, geometric, binomial, or discrete weighted distribution) or fall within a given range.
Shuffling
There are special considerations in play when applications use RNGs to shuffle a list of items.
Shuffling Method
The first consideration touches on the shuffling method. The Fisher–Yates shuffle method shuffles a list such that all permutations of that list are equally likely to occur, assuming the RNG it uses produces uniformly random numbers and can choose from among all permutations of that list. However, that method is also easy to mess up (see also Jeff Atwood, "The danger of naïveté"); I give a correct implementation in another document.
Choosing from Among All Permutations
The second consideration is present if the application uses PRNGs for shuffling. If the PRNG's period is less than the number of distinct permutations (arrangements) of a list, then there are some permutations that PRNG can't choose when it shuffles that list. (This is not the same as generating all permutations of a list, which, for a sufficiently large list size, can't be done by any computer in a reasonable time.)
The number of distinct permutations is the multinomial coefficient m! / (w_{1}! × w_{2}! × ... × w_{n}!), where m is the list's size, n is the number of different items in the list, x! means "x factorial", and w_{i} is the number of times the item identified by i appears in the list. Special cases of this are—
 n!, if the list consists of n different items, and
 (nm)! / m!^{n}, if the list is formed from m identical lists each with n different items.
In general, a PRNG with state length k bits, as shown in the table below, can't choose from among all the distinct permutations of a list with more items than the given maximum list size n (k is the base2 logarithm of n!, rounded up to an integer). (Note that a PRNG with state length k bits can't have a period greater than 2^{k}, so can't choose from among more than 2^{k} permutations.)
State length (k)  Maximum list size (n) 

64  20 
128  34 
226  52 
256  57 
512  98 
525  100 
A PRNG with state length less than the number of bits given below (k) can't choose from among all the distinct permutations of a list formed from m identical lists each with n different items, as shown in this table (k is the base2 logarithm of ((nm)! / m!^{n}), rounded up to an integer).
Number of lists (m)  Items per list (n)  Minimum state length (k) 

1  20  62 
2  20  140 
4  20  304 
1  52  226 
2  52  500 
1  60  273 
Whenever a statisticalrandom implementation or seeded RNG is otherwise called for, if an application is expected—
 to shuffle lists of size no larger than 100, then any PRNG used for shuffling is encouraged to have a period at least as high as the number of permutations of the largest list it is expected to shuffle. (See "Lack of randomness" in the BigDeal document by van Staveren for further discussion.)
 to shuffle lists of arbitrary size, or lists of size larger than 100, then any PRNG used for shuffling is encouraged to have a period at least as high as the number of permutations of an Xitem list, where X is the average expected size of lists to be shuffled (or, alternatively, 100 if the lists to be shuffled will usually be large). (Practically speaking, for sufficiently large list sizes, any given PRNG will not be able to randomly choose some permutations of the list.)
The PRNG in question should—
 meet or exceed the quality requirements of a statisticalrandom implementation, and
 have been initialized automatically with an unpredictable seed before use.
Motivation
In this document, I made the distinction between statisticalrandom and unpredictablerandom generators because that is how programming languages often present random number generators — they usually offer a generalpurpose RNG (such as C's rand
or Java's java.util.Random
) and sometimes an RNG intended for security purposes (such as java.security.SecureRandom
).
What has motivated me to write a more rigorous definition of random number generators is the fact that many applications still use weak RNGs. In my opinion, this is largely because most popular programming languages today—
 specify few and weak requirements on RNGs (such as C's
rand
),  specify a relatively weak generalpurpose RNG (such as Java's
java.math.Random
, although it also includes a much strongerSecureRandom
class),  implement RNGs by default that leave a bit to be desired (particularly the Mersenne Twister algorithm found in PHP's
mt_rand
as well as in Python and Ruby),  seed RNGs with a timestamp by default (such as the .NET Framework implementation of
System.Random
), and/or  leave the default seeding fixed (such as C's
rand
).
Conclusion
In conclusion, most applications that require random numbers usually want either unpredictability (cryptographic security), or speed and high quality. I believe that RNGs that meet the descriptions specified in the UnpredictableRandom Generators and StatisticalRandom Generators sections will meet the needs of those applications.
In addition, this document recommends using unpredictablerandom implementations in many cases, especially in computer and information security contexts, and recommends easier programming interfaces for both unpredictablerandom and statisticalrandom implementations in new programming languages.
I acknowledge—
 the commenters to the CodeProject version of this page, including Cryptonite, and
 Lee Daniel Crocker, who reviewed this document and gave comments.
Request for Comments
Feel free to send comments. They may help improve this page.
Comments on any aspect of the document are welcome, but answers to the following would be particularly appreciated.
 Have I characterized the randomness needs of applications properly?
 Did I cover the vast majority of applications that require randomness?
 Are there existing programming language APIs or software libraries, not mentioned in this document, that already meet the requirements for unpredictablerandom or statisticalrandom RNGs?
 Are there certain kinds of applications that require a different kind of RNG (unpredictablerandom, statisticalrandom, seeded, etc.) than I recommended?
 In a typical computer a consumer would have today:
 How many random numbers per second would an unpredictablerandom implementation generate? A statisticalrandom implementation?
 How many random numbers per second does a typical application using RNGs generate? Are there applications that usually generate considerably more random numbers than that per second?
Notes
^{(1)} For colored noise, this statement appears because multiple instances of a PRNG automatically seeded with a timestamp, when they are created at about the same time, run the risk of starting with the same seed and therefore generating the same sequence of random numbers.
^{(2)} This is because usual implementations of colored noise don't sample each point of the sample space more than once; rather, all the samples are generated, then, for some kinds of colored noise, a filter is applied to the samples.
^{(3)} Note that some PRNGs (such as xorshift128+
) are not well suited to serve as hash functions, because they don't mix their state before generating a random number from that state.
License
This page is licensed under A Public Domain dedication.