알고리즘 · LESSON 10
안전한 난수 만들기 — SHA
유니피커의 안전한 난수는 SHA라는 해시 기계로 만들어요. 이름은 어렵지만 원리는 쉬워요.
개념
SHA = 대표적인 해시 기계
SHA(Secure Hash Algorithm)는 글을 넣으면 정해진 길이의 해시(64자리)를 만드는 대표적인 방법이에요. 해시가 뭔지는 앞 수업 '해시란?'에서 배웠죠 (같은 입력 → 같은 해시, 한 글자만 바뀌어도 확 달라짐). 여기선 그 해시를 난수로 바꿔 추첨에 쓰는 법을 배워요.
왜 CSPRNG로 SHA가 좋아? 안전한 난수에 필요한 예측 불가 + 재현 가능을 SHA가 한꺼번에 만족해요. 시드만 정하면 필요한 만큼 만들 수 있고, 누구나 똑같이 계산해 검증할 수 있으며, 전 세계 표준이라 어디서나 같은 결과가 나와요.
실험
SHA를 난수로 바꾸기
SHA 해시는 사실 엄청 큰 숫자(16진수 64자리, 256비트)예요. 유니피커는 이 해시 전체를 계산한 뒤, 컴퓨터가 소수로 오차 없이 다룰 수 있는 상위 53비트만 잘라내 253으로 나눠서 0~1 사이 난수로 바꿔요.
글
왜 상위 53비트만 쓸까? 자바스크립트 같은 컴퓨터 연산은 53비트까지만 소수를 오차 없이 정확히 다룰 수 있어요. 256비트 해시 전체를 그대로 나누면 오차가 생기기 때문에, 해시의 상위 53비트만 잘라 253(=9,007,199,254,740,992)으로 나누면 정밀한 0~1 난수가 나와요. 왜 0~1로 만들까? 0~1 난수는 '만능 자'예요 — 곱하기만 하면 어떤 범위든 만들어요(예: 5명 중 뽑기 → 0~1 × 5). 퍼센트처럼 어디서나 통하는 공통 잣대라 한 번 만들어두면 두고두고 편해요.
실험
대량 난수 만들기 — 시드 + 번호
난수를 잔뜩 만들려면 시드 뒤에 번호를 붙여 SHA를 돌려요: SHA(시드|0), SHA(시드|1)… 각각 완전히 다른 난수가 나와요. 응모자마다 하나씩. (번호는 0부터 시작해요.)
시드는 어디서 올까? 유니피커는 받아온 DRAND 난수의 앞 16자리(16진수)를 추출해 10진수로 변환한 값을 시드로 써요. (예: 3947128560 같은 수)
시드
| 응모자 | SHA에 넣는 값 | SHA-256 해시 (일부만 표시) | 0~1 난수 |
|---|
속도 테스트난수를 대량 생성하는 데 걸린 시간을 체크해 보아요.
각자 독립이라 동시에(병렬) 만들 수 있어 수백만 개도 빨라요.
원리
해시 상위 53비트를 쓰는 이유
유니피커는 먼저 SHA 해시 전체(256비트)를 계산해요. 그 다음, 컴퓨터가 오차 없이 정밀하게 다룰 수 있는 상위 53비트만 잘라 난수로 써요. 256비트 전체의 예측 불가능성은 그대로 살리면서, 계산은 정확하게 하는 방식이에요.
2256가지약 1.2×1077 — 우주 원자 수보다 많아요
오차 없음상위 53비트는 컴퓨터가 소수로 정확히 다룰 수 있는 한계예요
재현 그대로같은 입력 → 같은 해시, 같은 상위 53비트
예측 불가엄청난 경우의 수라 아무도 못 맞혀요
참고 — 위 체험 데모에서는 화면에 보이기 쉽게 해시 전체를 줄여 표시할 때도 있지만, 실제 난수 계산에는 해시 전체를 구한 뒤 상위 53비트를 사용해요.
핵심 — SHA(시드 + 번호)로 안전한 난수를 필요한 만큼 만들고, 해시 전체 중 상위 53비트를 253으로 나눠 써요. 같은 시드면 누구나 같은 난수 → 검증 가능.
