랜덤초이스
7

랜덤 뽑기 원리와 신뢰성

컴퓨터 난수는 진짜 랜덤이 아니라는 말은 사실입니다. 하지만 그 말이 곧 믿을 수 없다는 뜻은 아닙니다. 어떤 원리로 만들어지고 어디까지 믿어도 되는지 알면 상황에 맞는 선택을 할 수 있습니다.

컴퓨터는 진짜 무작위를 만들지 못한다

컴퓨터는 정해진 명령을 정확히 수행하는 기계입니다. 같은 입력에 같은 출력을 내는 것이 존재 이유이므로, 본질적으로 예측 불가능한 값을 스스로 만들어낼 수 없습니다.

그래서 나온 것이 의사난수 생성기(PRNG)입니다. 시작값인 시드를 하나 받아 정해진 계산을 반복하면서, 겉보기에 무작위처럼 보이는 수열을 만들어냅니다. 시드가 같으면 언제나 같은 수열이 나옵니다.

진짜 무작위가 필요하면 컴퓨터 바깥에서 값을 가져와야 합니다. 운영체제는 키 입력 간격, 디스크 응답 시간, 하드웨어 잡음 같은 예측 불가능한 물리적 사건을 모아 엔트로피 풀을 만들고 이걸 난수의 재료로 씁니다.

의사난수는 어떻게 만들어지나

가장 이해하기 쉬운 예는 선형 합동 생성기(LCG)입니다. 현재 값에 어떤 수를 곱하고 다른 수를 더한 뒤 나머지를 취하는 방식으로 다음 값을 만듭니다. 단순하지만 하위 비트에 규칙성이 남는 등 품질 문제가 있어 요즘은 잘 쓰지 않습니다.

현대 브라우저의 Math.random()은 대부분 xorshift128+ 계열을 씁니다. 128비트 상태를 비트 시프트와 배타적 논리합으로 갱신하는 방식으로, LCG보다 훨씬 긴 주기와 좋은 통계적 성질을 갖습니다.

품질을 평가할 때는 균등성(모든 값이 고르게 나오는가), 주기(수열이 반복되기까지의 길이), 상관관계(앞 값에서 뒤 값이 유추되는가)를 봅니다. 현대 의사난수 생성기는 이 검사들을 통과하며 통계적으로는 진짜 난수와 구분하기 어렵습니다.

일반 난수를 믿어도 되는 범위

결론부터 말하면 이해관계가 크지 않은 대부분의 용도에는 충분합니다. 모둠 나누기, 메뉴 고르기, 발표 순서 정하기, 게임의 주사위 굴림 등에서 품질이 문제가 되는 경우는 사실상 없습니다.

한계는 예측 가능성입니다. 출력값을 충분히 많이 관찰하면 내부 상태를 역산할 수 있고 그러면 다음 값을 알 수 있습니다. 실제로 xorshift128+의 상태를 출력 몇 개로 복원하는 방법이 공개되어 있습니다.

또 하나의 한계는 시드입니다. 시드가 시간처럼 예측 가능한 값에서 나오면 같은 시각에 실행된 두 프로그램이 같은 수열을 만들 수 있습니다. 브라우저는 이 문제를 피하려고 시스템 엔트로피로 시드를 잡습니다.

암호학적 난수

예측 시도의 이득이 클 때는 암호학적으로 안전한 난수 생성기를 써야 합니다. 브라우저에서는 crypto.getRandomValues()가 이 역할을 합니다.

이 방식의 핵심 성질은 출력값을 아무리 많이 봐도 다음 값을 계산할 수 없다는 것입니다. 내부적으로 운영체제의 엔트로피 풀에서 시드를 받고 상태를 역산할 수 없는 암호 함수를 사용합니다.

비밀번호 생성, 인증 토큰, 상금이 걸린 추첨처럼 누군가 결과를 미리 알아내면 이득을 보는 상황이라면 반드시 이쪽을 써야 합니다. 이 사이트의 비밀번호 생성기는 이 방식을 사용합니다.

어떤 상황에 무엇을 쓸까

판단 기준은 간단합니다. 누군가 결과를 미리 알면 이득을 보는가. 이 질문에 그렇다고 답할 수 있으면 암호학적 난수를, 아니라면 일반 의사난수를 쓰면 됩니다.

속도 차이도 고려 대상입니다. 암호학적 난수는 상대적으로 느려서 수십만 개를 한꺼번에 만들어야 하는 시뮬레이션 같은 작업에는 부담이 됩니다. 반대로 몇 개에서 몇백 개 수준이라면 체감 차이가 없습니다.

  • 일반 의사난수로 충분: 모둠 나누기, 순서 정하기, 게임 주사위, 메뉴 고르기
  • 암호학적 난수 권장: 비밀번호, 인증 토큰, 상금이 걸린 추첨, 보안 키

시드와 재현 가능성

의사난수의 같은 시드면 같은 결과라는 성질은 단점만은 아닙니다. 실험이나 시뮬레이션에서는 결과를 재현할 수 있어야 검증이 가능하므로 시드를 기록해 두는 것이 표준적인 관행입니다.

추첨에서도 이 성질을 활용할 수 있습니다. 추첨 전에 시드를 공개하고 명단과 알고리즘을 함께 공개하면 누구나 같은 결과를 재현해 검증할 수 있습니다.

다만 시드를 미리 공개하면 결과도 미리 계산할 수 있으므로 순서가 중요합니다. 보통은 시드의 해시값을 먼저 공개하고 추첨 후에 시드 자체를 공개하는 방식으로 이 문제를 해결합니다.

몰림은 편향이 아니다

무작위 결과를 볼 때 사람들이 가장 자주 오해하는 것이 뭉침입니다. 동전을 스무 번 던져 앞면이 다섯 번 연속 나오면 뭔가 잘못된 것 같지만, 스무 번 안에 다섯 연속이 나올 확률은 약 4분의 1로 꽤 흔합니다.

사람이 머릿속으로 무작위처럼 보이는 수열을 만들면 오히려 지나치게 골고루 퍼진 결과가 나옵니다. 진짜 무작위는 뭉치고 비고 다시 뭉칩니다. 별이 하늘에 고르게 흩어지지 않고 성단을 이루는 것과 같습니다.

그래서 같은 사람이 또 뽑혔다는 것만으로는 편향의 근거가 되지 못합니다. 편향을 확인하려면 수백 번 이상 반복해 분포를 봐야 하고, 그렇게 검증된 알고리즘을 쓰는 것이 훨씬 실용적인 접근입니다.

여기서 바로 사용해 보기

글에서 설명한 내용을 아래에서 바로 확인해 볼 수 있습니다.

처음이라면 여기를 눌러 보세요
  • 한 줄에 하나씩 입력합니다.
  • 가중치를 쓰려면 이름 뒤에 *숫자를 붙입니다. 예: 민수*3
  • 가중치가 클수록 뽑힐 확률이 높아집니다.

가중치를 생략하면 1로 처리합니다. 헷갈리지 않도록 이름*숫자 형식으로 입력하는 것을 권장합니다.

결과

대기 중

?

아직 결과가 없습니다.

전체 기능으로 사용하기

전체 화면, 결과 저장 같은 기능은 도구 페이지에서 모두 쓸 수 있습니다.

자주 묻는 질문

그럼 일반 난수로 추첨해도 되나요?

경품 규모가 크지 않고 참가자가 결과를 예측해 이득을 볼 여지가 없다면 충분합니다. 고가 경품이나 참가자가 많은 이벤트라면 암호학적 난수를 쓰는 쪽이 안전하고, 그 사실을 공지에 밝히는 것도 신뢰에 도움이 됩니다.

주기가 다 돌면 결과가 반복되나요?

이론적으로는 그렇지만 실질적으로는 무의미합니다. xorshift128+의 주기는 2의 128제곱에서 1을 뺀 값으로, 초당 수십억 개를 뽑아도 우주의 나이보다 오래 걸립니다.

물리적 난수 생성기는 무엇인가요?

전자 잡음, 방사성 붕괴, 광자의 경로 같은 물리 현상을 측정해 값을 만드는 장치입니다. 예측이 원리적으로 불가능하지만 속도가 느리고 장비가 필요해, 보통은 이 값을 시드로 삼아 암호학적 생성기를 돌리는 방식으로 씁니다.

같은 결과가 두 번 나올 수도 있나요?

항목이 적으면 당연히 자주 일어납니다. 6면 주사위를 두 번 굴려 같은 눈이 나올 확률은 6분의 1입니다. 명단이 클수록 확률이 낮아지지만 0은 아닙니다.

이 사이트는 어떤 방식을 쓰나요?

일반 뽑기 도구는 브라우저의 의사난수를 피셔-예이츠 셔플과 거부 샘플링으로 처리해 편향 없이 배분합니다. 비밀번호 생성기처럼 보안이 필요한 도구는 암호학적 난수를 사용합니다.

함께 쓰면 좋은 도구

다른 가이드