java.util패키지에는 Random이라는 아주 큰 클래스 라이브러리가 있다. 해당 Random클래스는 자바1.0부터 지원했다.
Random클래스의 인스턴스는 일련의 의사 난수(진짜 난수와 비슷한 가짜 난수)를 생성한다. 난수는 무(無)에서 생성되는 것이 아니라'seed(씨앗)'라는 수의 값을 바탕으로 여러 연산을 수행하여 얻는다. Random클래스에는 48비트의 seed를 사용하고, 이 seed는 선형 합동법이라는 계산법에 의해 특정 수인 난수로 바뀐다.
Random클래스의 생성자는 두개가 있다
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
public Random(long seed) {
if (getClass() == Random.class)
this.seed = new AtomicLong(initialScramble(seed));
else {
// subclass might have overriden setSeed
this.seed = new AtomicLong();
setSeed(seed);
}
}
Random()은 seedUniquifier()을 실행하여 얻은 long값과 시스템의 현재 시간의 nano초를 XOR비트연산(^)을 통해서 새로운 long값을 아래 Random(long seed)생성자에 보내주는 방식이다.
위 논문과 시스템 시간을 XOR연산하기 때문에, Random()클래스가 seed를 통해 생성하는 난수는 사전 정의처럼 '다음 수를 예측할 수 없는 완전 무작위의 수' 까지는 아니다. 미미하지만 어느정도의 패턴이 있고 시스템 상, 아예 나오지 않는 수도 존재하기 때문이다.
해당 Random클래스에는 각 자료형에 맞게 난수를 가져올 수 있는 메서드가 정의돼 있다.

컴퓨터 과학에서는 보통 특정 입력값이나 컴퓨터 환경에 따라 무작위로 선택한 것처럼 보이는 난수를 생성하는데, 그 입력값이나 컴퓨터 환경이 같다면 결과값은 항상 같다. 결국 컴퓨터가 생성한 난수는 모두 미리 계산해 둔 '의사 난수'이다.
컴퓨터는 계산된 결과만 가지고 난수를 생성하는데, 이 계산된 결과는 입력값에 의해 결정되므로 이 값으로 임의의 난수를 생성할 수는 없다. 프로그램에서 매번 같은 방법으로 이 값을 가져오면 처음 실행할 때 이외에는 난수라고 할 수 없기에 보통 seed라고 부르는 수를 매개변수로 매번 다르게 전달하여 다른 의사 난수를 생성해야 한다. 보통 seed값은 시간에 따라 다르게 생성된다.
선형 합동법은 보편적으로 사용하는 의사 난수 생성기이다. 현재 의사 난숫값을 A배 하고 C를 더한 다음, M으로 나눈 나머지를 의사 난수로 선택하는 방법이다. 계산 공식이 간단해 연산이 빠르고 메모리를 적게 사용하지만, 수를 바꾸는(modulate) 연산을 할 때는 변수의 최댓값을 주기로 가지므로 자료형 이상의 주기를 사용할 수는 없다. 선형 합동법은 간단한 공식과 주기의 제한으로 '예측 불가능성'이 없다. 따라서 선형 합동법을 암호 기술에는 사용할 수 없다. C의 rand함수, 자바의 java.util.Random 클래스는 모두 선형 합동법을 사용한다.
https://www.ams.org/journals/mcom/1999-68-225/S0025-5718-99-00996-5/S0025-5718-99-00996-5.pdf
선형 합동법 논문이다.