Implementation of Linear Congruential Pseudorandom Number Generation in Java

Pseudorandom number generators produce sequences that appear random but are generated deterministically using mathematical formulas. Java's Random class implements a linear congruential generator (LCG) based on a 48-bit seed value.

Core Algorithm Implementation

The LCG algorithm follows the recurrence relation:

Xn+1 = (a * Xn + c) mod m

In Java's implementation:

private static final long coefficient = 0x5DEECE66DL;
private static final long increment = 0xBL;
private static final long modulus = (1L << 48) - 1;

protected int generateBits(int bitCount) {
    long currentSeed, nextSeed;
    AtomicLong seedRef = this.seed;
    do {
        currentSeed = seedRef.get();
        nextSeed = (currentSeed * coefficient + increment) & modulus;
    } while (!seedRef.compareAndSet(currentSeed, nextSeed));
    return (int)(nextSeed >>> (48 - bitCount));
}

The bitwise AND operation with modulus is equivalent to modulo 2^48, as modulus = 2^48 - 1 creates a bitmask that preserves the lower 48 bits.

Seed Initialization

Java employs sophisticated seed generation combining system time and multiplicative scrambling:

private static long generateUniqueSeed() {
    for (;;) {
        long current = seedUniquifier.get();
        long next = current * 181783497276652981L;
        if (seedUniquifier.compareAndSet(current, next))
            return next;
    }
}

public Random() {
    this(generateUniqueSeed() ^ System.nanoTime());
}

This approach combines:

  • A base seed value (8682522807148012L)
  • Multiplicative scrambling with a large prime constant
  • XOR with high-resolusion system time

Bounded Random Number Generation

For generating integers within a specific range [0, n):

public int nextBoundedInt(int upperBound) {
    if (upperBound <= 0)
        throw new IllegalArgumentException("Upper bound must be positive");

    if ((upperBound & -upperBound) == upperBound)
        return (int)((upperBound * (long)generateBits(31)) >> 31);

    int randomBits, result;
    do {
        randomBits = generateBits(31);
        result = randomBits % upperBound;
    } while (randomBits - result + (upperBound - 1) < 0);
    return result;
}

The condition (upperBound & -upperBound) == upperBound efficiently checks if the upper bound is a power of two using two's complement properties.

Algorithm Characteristics

  • Period: The generator has a maximum period of 2^48
  • Thread Safety: Implemented using atomic operations on the seed
  • Limitations: Sequential correlation between generated values
  • Cryptographic Security: Not suitable for security-sensitive applications

For cryptographic purposes, use java.security.SecureRandom which provides cryptographically strong random numbers.

Tags: java random number generation Linear Congruential Generator algorithms programming

Posted on Sat, 17 Oct 2026 16:31:06 +0000 by lipun4u