glenn-syj / more-effective-java

이펙티브 자바를 읽으며 자바를 더 효율적으로 공부합니다
4 stars 5 forks source link

[MEJ-014] Random 클래스의 난수 생성 방식에 대해 #229

Open undeadtimo opened 1 month ago

undeadtimo commented 1 month ago

Based on : #228 by @FickleBoBo


실제로 난수 생성 방식을 이용해 png 파일을 구현함으로써 일정한 패턴이 반복될 수 있음을 확인하여 이해가 쉬웠습니다.

또한, 실제 프로젝트 경험과 연관지어 설명해주시니 공감하며 지식을 습득할 수 있었습니다.

이번에도 좋은 글을 작성해주셔서 감사합니다.

FickleBoBo님의 이번 난수 생성 알고리즘에 대한 글을 읽고 Random 클래스가 정확히 어떤 방식으로 난수를 생성하는지 궁금하여 그 부분을 조사해보았습니다.


Random 클래스는 기본적으로 다음 수식을 바탕으로 난수를 생성합니다.

Xn+1 = (aXn + C) % m

X의 n번째 수에 a를 곱한 후 C를 더한 값을 m으로 모듈러 연산을 해준 값이 X의 n + 1번째 값임을 나타내는 식입니다.

여기서 a, C, m은 Random 클래스에 고정되어 있습니다.

이러한 값들은 수학적 성질을 바탕으로 최대한 예측되지 않는 숫자를 도출해내기 위한 상수들입니다.

단, Random 클래스를 만들 때마다 다르게 지정되는 것이 있는데 그것은 'seed'를 말합니다. 여기서 seed란 X의 첫 번째 값을 말하며 해당 seed에 위의 수식을 적용하면서 연속되 난수들이 생성되는 것입니다.

Random random = new Random(255);

이러한 방식으로 직접 255라는 seed 값을 지정해줄 수도 있지만, 따로 seed 값을 지정해주지 않을 경우, System.currentTimeMillis()의 값, 즉 현재 시스템상의 시간을 밀리세컨드 단위로 나타낸 값이 시드 값으로 적용됩니다.

어떠한 seed 값이 설정되느냐에 따라 예측가능한 숫자가 난수로 생성되기도 하고, 패턴의 주기가 길어지거나 짧아질 수도 있습니다. 따라서, FickleBoBo님의 코드대로 이미지 파일을 생성하면 한 눈에 보아도 일정한 패턴들이 보이는 것입니다.


Reference :

https://www.baeldung.com/java-random-seed