Random Numbers in Java

This post is about alternatives to the java.util.Random class, the most commonly used method to generate random numbers in Java.

Dice players of antiquity

Random: Playing the odds in Ancient Rome Osteria della Via de Mercurio

 java.util.Random

This class generates “random enough” values, which are described as having an informal level of randomness. Such numbers have a superficial appearance of randomness to an observer, usually a human observer, not a machine. These are considered low-quality random numbers. They should never be used in any security application.

True randomly-generated numbers must have the following characteristics:

  • Any number is equally likely to be generated on every iteration. This is also known as a uniformly distributed series of numbers.
  • The second criterion follows directly: No dependency exists between successive numbers as they are generated.

Alternatives to better match your random needs

Neil Coffey of Javamex describes three alternative random number generation methods. Each approach continues to use class java.util.Random, while replacing the underlying algorithm. The first, called the XORShift generator, produces medium-quality random numbers very quickly, with only a single state variable and very simple code. This method is very well suited to J2ME games.

The next algorithm generates much higher-quality random numbers. It is a combined generator, using two XORShift generators of the sort described above. Mr. Coffey provides the code and explanation for the algorithm. This combined XORShift yields good-quality random numbers. It is suitable for non-gambling games and simulations, although it runs slightly slower than java.util.Random.

A cryptographic quality random number generator should have the following properties:

  1. It should be impossible to predict prior and future numbers from any number generated;
  2. The numbers should have no discernible biases;
  3. The generator has a large period;
  4. The generator can seed itself at any position within that period with equal probability.

A cryptographically secure random number generator is appropriate for security applications such as producing a web-server session id or picking encryption keys. Very high-quality random numbers are generated using java.security.SecureRandom as the replacement for java.util.Random. The trade-off in quality versus CPU cycle consumption is hardly surprising.  java.security.SecureRandom runs 20 to 30 times slower than any of the other algorithms.

Relative comparison between the methods

Here is a very simplified way of understanding the difference between each algorithm.

Let’s say that we need to generate a 128-bit encryption key. java.security.SecureRandom actually picks from a pool of 2 raised to the 127th power number of possible keys. Of course java.util.Random can also be used to generate a 128-bit key. However, the values will be selected from a smaller pool of numbers, on the order of 2 raised to the 47th power number of possible keys. This is because java.util.Random has a much shorter period, equal to 2 raised to the 48th power.

The single XORShift generator method falls between the two, as it has a slightly longer period, of 2 raised to the 64th power. The combined XORShift generator approach extends the period a bit further.

Note than neither java.util.Random nor either of the XORShift generators are seeded randomly. This is why java.security.SecureRandom, with a machine-generated and much more truly random random seed, is superior.

* The machine-generated random seed is what is called entropy in random number generators.

The URI to TrackBack this entry is: https://myindigolives.wordpress.com/2010/06/14/random-numbers-in-java/trackback/

RSS feed for comments on this post.

3 CommentsLeave a comment

  1. A bit of reciprocated comments here. You should look at this class, written many years ago by a good friend of mine.

    http://codeproject.com/KB/recipes/mersennetwisterclass.aspx

    It’s written in C++ but should be easy enough to convert to C# or Java.

    • Thank you for the suggestion!

      I had a look and quite enjoyed the entire http://www.codeproject.com site. The Mersennet Twister (MT) algorithm seems to be the standard now for pseudo-random number generators. However, I didn’t anticipate that speed not accuracy was the advantage of using MT over ordinary rand()! Here’s the surprise ending from MT class article by Dave Loeser, written in 2003 (thus the mention of PentiumIII):

      results for rand() appear to come closer to the desired 50/50 distribution of a coin flip than that of MT…This leaves us with only speed as the determining factor in the decision to use the MT algorithm…The pursuit of the perfect PRNG is an ongoing effort that eludes computer scientist and mathematicians alike. The Mersenne Twister is generally considered to be fast, small and provides equal distribution. I like the fact that I can generate 1,000,000,000 random numbers in about 0.45 seconds on a PIII 900mhz machine.

  2. […] For the curious, I wrote a little more about Randall Munroe, xkcd with love and geohashing and even random numbers, in Java. […]


Comments welcomed! Less enthusiastic about spam.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: