난수 생성기
원하는 범위에서 중복 있음/없음을 선택해 하나 또는 여러 개의 난수를 생성합니다 — 암호학적 난수성을 사용합니다.
조회수 1,445회
숫자는 실제로 어떻게 생성될까요
모든 "무작위"가 같은 것은 아닙니다. 모든 브라우저에 있는 Math.random()은 빠른 의사 난수 생성기입니다 — 내부적으로는 결정론적이며, 원리적으로 내부 상태를 아는 사람이라면 예측할 수 있습니다. 이 때문에 실제 상금이 걸린 추첨처럼 보안이 중요한 용도에는 적합하지 않습니다. 이 도구는 대신 브라우저에 내장된 암호학적으로 안전한 난수 생성기인 crypto.getRandomValues()를 사용합니다. 이는 운영체제의 엔트로피 소스에서 값을 얻으며, 원리적으로도 예측이 불가능합니다.
그러나 안전한 난수 소스를 갖는 것은 문제의 절반만 해결합니다. 난수 값을 특정 범위(예: 1-100)에 단순하게 매핑하는 방법 — random % 100을 사용하는 방식 — 은 미묘하지만 실재하는 모듈로 편향을 만들어냅니다. 생성기의 원시 출력 범위가 보통 100의 정확한 배수가 아니기 때문에, 일부 나머지 값이 다른 값보다 아주 조금 더 자주 나오게 됩니다. 이 편향은 작지만 실재하며 여러 번 추첨할수록 누적됩니다 — 공정해야 할 추첨에는 결코 있어서는 안 되는 종류의 문제입니다.
해결책은 거부 샘플링(rejection sampling)입니다: 모든 원시 값을 모듈로 연산으로 강제로 범위 안에 욱여넣는 대신, 범위를 벗어난 원시 값은 버리고 목표 범위의 정확한 배수 안에 깔끔하게 들어맞는 값이 나올 때까지 새로 뽑습니다. 이렇게 하면 진정으로 균일한 분포가 보장됩니다 — 범위 내 모든 숫자가 정확히 동일한 확률을 갖습니다 — 대가로 가끔 한두 번 더 뽑아야 할 수도 있지만, 이 정도 속도에서는 전혀 체감되지 않습니다.
최솟값과 최댓값, 필요한 개수를 선택하십시오. 같은 참가자나 같은 항목이 두 번 당첨되어서는 안 되는 추첨, 경품 뽑기, 표본 추출, 게임에 필요한 중복 없음을 체크하면 반복을 방지할 수 있습니다. 모든 처리는 사용자의 기기에서 이루어집니다 — 어떤 숫자도 어디로도 전송되거나 저장되지 않으며, 페이지를 새로고침하면 완전히 새로운 추첨이 이루어집니다.
알아두면 좋은 점
- 모듈로 편향은 몇 번의 추첨에서는 보이지 않지만, 수천 번에 걸쳐서는 통계적으로 감지할 수 있게 됩니다 — 거부 샘플링은 이를 줄이는 데 그치지 않고 완전히 제거합니다.
crypto.getRandomValues()가 "암호학적으로 안전하다"는 것은, 이전 출력을 본 사람이라 해도 그 출력을 예측할 수 없다는 뜻입니다 — 이는Math.random()이 명백히 갖고 있지 않으며 애초에 그렇게 설계되지도 않은 특성입니다.- 범위는 양쪽 끝을 모두 포함합니다: 1-10 추첨은 1과 10을 모두 만들어낼 수 있으며, 그 사이에 엄격히 있는 값만 나오는 것이 아닙니다.
- 감사 가능한 추첨을 위해서는 참가자에게 1부터 N까지 번호를 매기고 그에 맞게 범위를 설정한 뒤 중복 없음을 활성화하고 결과의 스크린샷을 찍으십시오. 추첨 후에는 서버 측에 아무것도 저장되지 않기 때문입니다.
자주 묻는 질문
이 숫자들은 정말로 무작위인가요, 아니면 그저 "충분히 무작위"인가요?
이 숫자들은 운영체제의 암호학적 엔트로피 소스에서 값을 얻는 crypto.getRandomValues()에서 나옵니다 - 대부분의 간단한 난수 스크립트가 사용하는 단순한 Math.random()과 달리, 실제로뿐 아니라 원리적으로도 예측이 불가능합니다.
모듈로 편향이란 무엇이며 이 도구에도 있나요?
난수 값을 random % N으로 단순하게 범위에 매핑하면 일부 숫자가 다른 숫자보다 살짝 더 자주 나오게 됩니다. 생성기의 원시 범위가 보통 N의 정확한 배수가 아니기 때문입니다. 이 도구는 거부 샘플링으로 이를 방지합니다: 범위를 벗어난 원시 값은 버려지고, 균일한 결과가 보장될 때까지 다시 뽑습니다.
거부 샘플링이란 쉽게 말해 무엇인가요?
모든 난수 값을 모듈로 연산으로 강제로 범위에 욱여넣는 대신, 편향을 만들어낼 값은 단순히 버리고 새로운 값을 뽑습니다 - 범위 안에 완전히 균등하게 들어맞는 값이 나올 때까지 이를 반복합니다. 비용은 가끔 한 번 더 뽑아야 한다는 것이고, 이점은 진정으로 균일한 결과를 얻는다는 것입니다.
경품 추첨에 사용할 수 있나요?
네. 참가자에게 1부터 N까지 번호를 매기고 그에 맞게 범위를 설정한 뒤, 중복 없음을 활성화하고 필요한 만큼 당첨자를 생성하십시오. 추첨 후에는 결과가 어디에도 저장되지 않으므로 기록용으로 스크린샷을 찍어 두십시오.
최솟값과 최댓값이 모두 범위에 포함되나요?
네 - 범위는 양쪽 끝을 모두 포함합니다. 1-10 추첨은 모자에서 번호가 적힌 종이를 뽑는 것과 정확히 똑같이 1과 10을 모두 만들어낼 수 있습니다.
비슷한 도구
문제 신고하기
난수 생성기
댓글
아직 댓글이 없습니다 — 첫 댓글을 남겨보세요!