번호 생성기의 '랜덤'은 어디서 오나 — 의사난수와 공정한 셔플

확률 기초 · 2026-10-01 · 4분 읽기

컴퓨터는 어떻게 무작위 번호를 만들까요. 의사난수의 원리, 이 사이트 생성기가 번호를 뽑는 실제 순서, 피셔-예이츠 방식과 거절 샘플링이 공정한 이유를 정리합니다.

로또 1등 당첨자 중 약 66%가 자동 선택이었습니다(제262회 이후 기준). 자동 번호는 판매점 단말기의 컴퓨터가 고릅니다. 이 사이트의 번호 생성기도 마찬가지입니다. 그런데 정해진 명령대로만 움직이는 컴퓨터가 어떻게 '무작위'를 만들어 낼까요?

컴퓨터는 원래 무작위를 못 만듭니다

컴퓨터 프로그램은 같은 입력을 넣으면 항상 같은 결과를 냅니다. 그래서 컴퓨터가 만드는 대부분의 난수는 의사난수(pseudo-random number) 입니다. 어떤 시작값(시드)에서 출발해 정해진 수식을 반복 적용하면, 겉보기에는 무작위처럼 보이는 숫자열이 나옵니다. 시드가 같으면 숫자열도 똑같이 반복됩니다.

웹 브라우저의 Math.random()도 의사난수입니다. 크롬 등 주요 브라우저는 xorshift128+라는 빠른 알고리즘을 씁니다. 게임이나 시뮬레이션에는 충분히 좋지만, 출력 몇 개를 보면 다음 값을 추측할 수 있어 보안 용도로는 쓰지 않습니다.

이 사이트의 생성기는 어떻게 뽑나

이 사이트의 번호 생성기도 브라우저의 Math.random()을 씁니다. 코드가 하는 일을 순서대로 적으면 이렇습니다.

  1. 1부터 45까지 중 제외수와 고정수를 뺀 나머지를 후보 목록으로 만듭니다.
  2. 후보 목록에서 무작위로 한 칸을 골라 꺼내고, 꺼낸 번호는 목록에서 지웁니다.
  3. 고정수와 합쳐 여섯 개가 될 때까지 2번을 반복합니다.
  4. 완성된 조합이 체크해 둔 특수 패턴 16가지 중 하나에 걸리면 조합 전체를 버리고 1번부터 다시 뽑습니다. 최대 1만 번까지 시도합니다.

화면의 '생성 이력 · 과정 로그'를 펼치면 몇 번째 시도에서 어떤 조합이 어떤 패턴 때문에 버려졌는지 그대로 보입니다.

이 방식이 공정한 이유

2번 단계는 피셔-예이츠 방식 그대로입니다. 1938년 통계학자 로널드 피셔와 프랭크 예이츠는 종이와 연필로 무작위 순서를 만드는 법을 소개했습니다. 남은 숫자 중 하나를 무작위로 골라 적고, 그 숫자를 목록에서 지운 뒤 반복하는 방법입니다. 1964년 리처드 더스텐펠드가 이를 컴퓨터용으로 다듬은 것이 오늘날 프로그래머들이 쓰는 '피셔-예이츠 셔플'입니다. 남은 후보가 모두 같은 확률로 뽑히므로, 고정수를 포함하는 조합들은 서로 정확히 같은 확률로 나옵니다.

4번 단계는 거절 샘플링입니다. 패턴에 걸린 조합에서 번호 하나만 바꾸는 것이 아니라 조합 전체를 버리고 처음부터 다시 뽑습니다. 그래서 걸러 낸 뒤에도 남은 조합들끼리는 확률이 여전히 똑같습니다. 필터가 특정 번호를 편애하게 만들지 않는다는 뜻입니다.

흔한 구현 실수와 비교하면

난수가 좋아도 뽑는 방법이 틀리면 결과가 치우칩니다. 자주 보이는 실수 두 가지가 있습니다.

실수 1: 무작위 정렬. 배열을 '무작위 비교 함수'로 정렬하는 방법은 코드가 짧아서 자주 쓰이지만, 정렬 알고리즘에 따라 특정 위치에 특정 값이 더 자주 남는 편향이 생깁니다.

실수 2: 나머지 연산 편향. 0~255 사이 정수 난수를 45로 나눈 나머지를 쓰면, 256이 45로 나누어떨어지지 않기 때문에 앞쪽 31개 번호가 뒤쪽보다 조금 더 자주 나옵니다(6/256 대 5/256).

이 사이트의 코드는 둘 다 해당하지 않습니다. 정렬로 섞지 않고 한 칸씩 꺼내며, Math.random()이 주는 0 이상 1 미만의 실수에 후보 개수를 곱해 내림하는 방식이라 나머지 연산 편향도 생기지 않습니다. 이때 남는 오차는 10조분의 1보다도 작은 수준입니다.

암호학적 난수가 필요할까

보안이 필요한 곳에서는 암호학적으로 안전한 난수 생성기를 씁니다. 운영체제가 하드웨어 잡음 같은 물리적 엔트로피를 모아 시드를 만들고, 출력에서 다음 값을 역추적할 수 없도록 설계된 방식입니다. 브라우저에서는 crypto.getRandomValues()가 이 역할을 합니다.

Math.random()은 이런 보장이 없어서 비밀번호나 인증 토큰을 만드는 데는 쓰면 안 됩니다. 하지만 번호 생성기에는 지켜야 할 비밀이 없습니다. 누군가 내가 받은 번호를 미리 짐작한다고 해서 잃을 것이 없고, 어떤 번호든 1등 확률은 같기 때문입니다. 필요한 것은 45개 번호가 고르게 나오는 것이고, Math.random()은 그 조건을 충분히 만족합니다.

실제 추첨은 물리적 무작위

참고로 매주 토요일 추첨은 컴퓨터가 아니라 공기 혼합식 추첨기로 합니다. 45개 공을 바람으로 섞어 하나씩 뽑아내는 방식이고, 공의 무게와 크기는 추첨 전에 검사합니다. 시드나 알고리즘 자체가 없는 물리적 무작위입니다. 34번 출현 횟수 글에서 본 것처럼, 1243회 동안의 출현 분포도 무작위 예상 범위 안에 있습니다.

좋은 생성기를 고르는 기준

확인할 점좋은 예이 사이트
난수 출처검증된 의사난수 또는 암호학적 난수Math.random()
뽑는 방식피셔-예이츠 방식, 거절 샘플링둘 다 사용
과정 공개버린 조합과 이유를 보여 줌과정 로그 제공
확률에 대한 주장확률을 바꾼다고 말하지 않음패턴 필터는 확률이 아니라 겹침에 관한 것

과거 데이터를 분석해 '나올 번호'를 골라 준다고 주장하는 생성기는 조심하는 것이 좋습니다. 공에 기억이 없는 한, 어떤 생성기도 1등 확률을 8,145,060분의 1보다 높일 수 없습니다. 생성기가 할 수 있는 정직한 일은 편향 없이 고르는 것, 그리고 원한다면 사람들이 몰리는 조합을 피하는 것뿐입니다.

자동·수동 비율은 동행복권 발표(제262~1209회 1등 기준, 자동 65.9%)를 인용했습니다.

지난 추첨 기록을 정리한 것이며 다음 회차를 예측하지 않습니다. 어떤 6개를 고르든 1등 확률은 1/8,145,060으로 같습니다. 당첨번호 출처: 동행복권.