Random and SecureRandom in Java

Naveen AnamaneniUpdated · 4 min read

Java has two main classes for random numbers. java.util.Random produces pseudo-random numbers: they look random but come from a formula, so the same seed gives the same sequence every time. It is fast and ideal for games, simulations and tests. java.security.SecureRandom produces numbers that are unpredictable, even to someone who has seen earlier values. It is used for passwords, tokens, keys and anything security-related. The basics of random numbers were introduced in "Generating Random Numbers"; in this lesson, you will learn both classes in depth.

Declaration

Declaration
public class Random implements RandomGenerator, Serializable
public class SecureRandom extends Random

RandomGenerator (Java 17) is the common interface for all random number generators.

Methods of Random

MethodDescription
nextInt()It is used to get any random int.
nextInt(bound)It returns a number from 0 (included) to bound (excluded).
nextInt(origin, bound)It returns a number from origin to bound - 1 (Java 17).
nextDouble()It returns a double from 0.0 to just under 1.0.
nextBoolean()It returns true or false.
nextGaussian()It returns a number from a normal ("bell curve") distribution.
nextBytes(byte[] b)It fills an array with random bytes.
ints(n, origin, bound)It returns an IntStream of n random numbers.

Example: Repeatable Random Numbers with a Seed

Let's see an example where two generators with the same seed give the same numbers.

Seeded.java▶ Try it
import java.util.Random;
 
public class Seeded {
    public static void main(String[] args) {
        Random a = new Random(42);
        Random b = new Random(42);
 
        for (int i = 0; i < 3; i++) {
            System.out.println(a.nextInt(100) + " " + b.nextInt(100));
        }
 
        Random dice = new Random(7);
        System.out.println("Dice: " + dice.ints(5, 1, 7).boxed().toList());
        System.out.println("Between 10 and 20: " + dice.nextInt(10, 21));
    }
}
Output
30 30
63 63
48 48
Dice: [5, 3, 4, 5, 5]
Between 10 and 20: 14

Explanation: new Random(42) starts the formula from the seed 42, so both generators produce exactly the same sequence. This makes tests and simulations repeatable. ints(5, 1, 7) gives a stream of five dice rolls from 1 to 6, and nextInt(10, 21) gives a number from 10 to 20.

SecureRandom

SecureRandom uses the operating system's source of randomness (such as hardware noise) so its output can't be predicted. It has the same methods as Random, because it extends it.

Tokens.java▶ Try it
import java.security.SecureRandom;
import java.util.Base64;
 
public class Tokens {
    public static void main(String[] args) {
        SecureRandom secure = new SecureRandom();
 
        byte[] bytes = new byte[24];
        secure.nextBytes(bytes);
        String token = Base64.getUrlEncoder().withoutPadding()
                             .encodeToString(bytes);
        System.out.println("Reset token: " + token);
 
        int otp = secure.nextInt(100_000, 1_000_000);
        System.out.println("OTP: " + otp);
        System.out.println("Algorithm: " + secure.getAlgorithm());
    }
}
Output
Reset token: 6j3nabZpsoMUJj8Xcft9b4niBpk9_aFw
OTP: 536977
Algorithm: NativePRNG

Explanation: 24 random bytes encoded with URL-safe Base64 make a 32-character token that is safe for a password-reset link. The six-digit OTP comes from nextInt(100000, 1000000). The algorithm name depends on the operating system.

Random vs SecureRandom

RandomSecureRandom
Packagejava.utiljava.security
PredictableYes, from the seedNo
SpeedFastSlower
Repeatable with a seedYesNo (seeding only adds randomness)
Use forGames, simulations, shuffling, testsPasswords, tokens, OTPs, keys, salts

Common Mistakes

Using Random or Math.random() for OTPs and tokens. Use SecureRandom.

Creating a new Random inside a loop. Create one and reuse it.

Expecting nextInt(10) to include 10. The bound is excluded.

Practice

  1. Easy: Simulate 1,000 coin flips with a seeded Random and print how many were heads.
  2. Harder: Write a password generator with SecureRandom that builds a 12-character password with at least one upper-case letter, one digit and one symbol.

Quick check: Random and SecureRandom

4 questions
1Two Random objects with the same seed produce...
2Which class should create password-reset tokens?
3What range does nextInt(1, 7) produce?
4Which is better for many threads?

Key Takeaways

Was this tutorial helpful?

Lesson 338 of 482