Random numbers in Java

In this section, we look at methods for generating series of random numbers in Java. By "random", we usually mean something like "unpredictable and unbiased". Or put another way, an ideal random number generator (RNG) would generate a series of numbers within a particular range where:

Unfortunately, these goals are extremely difficult or inefficient to achieve on a computer, and impossible to achieve in pure software. So in practice, we generally settle for a generator that produces numbers that look random enough to the observer. By "observer" we could mean the human using the program, or a computer routine that consumes the random number, such as an encryption key generator. As we'll explore in detail in the following sections, what is "random enough" depends on the application. Additionally, whether an "observer" can detect non-randomness in the numbers generated depends on what that observer is— a human looking at a simulated dice roll might not spot any pattern, but a computer program performing statistical tests might. We'll come back to such issues in more detail later, but start here with some common situations that require an "informal" level of randomness.

Appropriate use of random numbers

One additional issue which you may need to consider in your application is the use that you put to random numbers. Even with the best underlying random number generator in the world, you still need to be careful. For example, various "scratch card" gambling games need to contain ostensibly random numbers, but which are potentially "rigged" in some way so that certain forms of winning have certain odds. If the algorithms for putting the scratch cards together from the underlying random number generators are not carefully designed, it has been shown that extremely simple statistical techniques can in some cases be used to "crack" the cards. The issue is not about the choice of underlying generator in this case. We don't examine this issue in detail at present, but as a rule of thumb, algorithms which rely on the "natural" statistics of random combinations will be much less prone to the type of problem illustrated by lottery scratch games such as the Ontario Tic Tac Toe game.

Random numbers if you're not too fussy

The way of generating random numbers in Java that most people know about is using the java.util.Random class.

For reasons we'll come to later, this class is generally a suitable generator for applications that need informal levels of randomness, such as the dice roll or starting position of the baddy in a game. Generally, Random is used as follows:

For example, the following code will print out 10 imaginary "dice rolls":

Random diceRoller = new Random();
for (int i = 0; i < 10; i++) {
  int roll = diceRoller.nextInt(6) + 1;

Here, we use a variant of the nextInt() method that takes an upper bound to the size of random integer produced. Calling nextInt(6) produces a random number (or at least, a number that looks random to the "casual observer") in the range 0 to 5 inclusive. Then, we add 1 to get a number in the traditional dice range of 1 to 6.

With some care, the Java Random class is suitable for informal applications, particularly if we actually use the class properly. However, there are some cases where other means of generation are more suitable, which we discuss below. If you do choose to use java.util.Random, you are strongly advised to read through the section discussing the weaknesses and appropriate use of java.util.Random. Reliance on the class without understanding some of these issues could invalidate your research results, skew your test harnesses or make your game algorithm less effective. In short:

The java.lang.Random class generates poor quality random numbers. It is suitable only for "casual" use. It should certainly be avoided in any security-related application, and in many other cases, other generators are more suitable.

As we will discuss below, notable cases where java.util.Random is not suitable include:

Alternatives to java.util.Random

For all but the most informal levels of randomness, you should consider using an alternative to java.util.Random. In this section, we discuss various alternative random number generation techniques in Java.

Tips on using random numbers

Whatever the method you use to generate "raw" random numbers, even if that method is perform (and of course, none is!), occasional issues remain in how you then use those random nubmers. In later sections, we consider:

1. What we're describing here is sometimes more specifically called a uniform random number generator. We could equally have a generator where numbers occur randomly with some non-linear distribution. For example, in a later section, we discuss generating numbers with a normal distribution, which is needed in certain simulation applications.