Skip to main content
KO
guide

Fair Random Picking — How Random Selection Works and Practical Uses

2026-04-11 · 8 min read

무작위성이란 무엇인가

우리는 일상에서 “랜덤”이라는 단어를 자주 사용합니다. 점심 메뉴를 랜덤으로 고르고, 발표 순서를 랜덤으로 정하고, 당첨자를 랜덤으로 뽑습니다. 하지만 진정한 의미의 **무작위(randomness)**란 정확히 무엇일까요?

수학적으로 무작위성은 결과를 예측할 수 없고, 모든 가능한 결과가 동등한 확률로 발생하는 상태를 의미합니다. 동전 던지기를 예로 들면, 앞면과 뒷면이 각각 정확히 50%의 확률로 나와야 하며, 이전 결과가 다음 결과에 영향을 미치지 않아야 합니다.

그런데 컴퓨터는 본질적으로 결정적(deterministic) 기계입니다. 같은 입력을 주면 항상 같은 출력을 내놓도록 설계되어 있습니다. 그렇다면 컴퓨터는 어떻게 “무작위” 수를 만들어 낼 수 있을까요? 이 질문에 대한 답이 바로 **의사 난수 생성기(PRNG)**와 **암호학적 난수 생성기(CSPRNG)**의 차이에 있습니다.


Math.random()의 한계와 crypto API

Math.random()은 왜 부족한가

자바스크립트에서 가장 흔히 사용하는 난수 함수인 Math.random()은 **의사 난수 생성기(Pseudo-Random Number Generator, PRNG)**입니다. 내부적으로 시드(seed) 값과 수학적 알고리즘을 사용하여 난수처럼 보이는 수열을 만들어냅니다.

Math.random()의 주요 한계점은 다음과 같습니다:

  • 예측 가능성: 시드 값을 알면 이후의 모든 숫자를 예측할 수 있습니다. 브라우저 내부의 PRNG 상태를 역공학적으로 알아낼 수 있다는 연구 결과도 존재합니다.
  • 균일성 부족: 특정 범위의 정수로 변환할 때 Math.floor(Math.random() * N) 패턴을 사용하면 미세한 편향(modulo bias)이 발생할 수 있습니다. N이 2의 거듭제곱이 아닌 경우, 일부 숫자가 다른 숫자보다 약간 더 자주 나타납니다.
  • 보안 부적합: 암호학적 목적으로는 사용해서는 안 됩니다. 추첨이나 복권 등 공정성이 중요한 상황에서도 신뢰하기 어렵습니다.

crypto.getRandomValues() — 더 나은 대안

Web Crypto API의 crypto.getRandomValues()는 **암호학적으로 안전한 난수 생성기(CSPRNG)**입니다. 운영체제의 엔트로피 소스(하드웨어 노이즈, 사용자 입력 타이밍, 디스크 I/O 등)를 활용하여 진정한 무작위에 가까운 수를 생성합니다.

이 API의 장점은 다음과 같습니다:

  • 예측 불가능: 이전 출력값으로 다음 값을 유추할 수 없습니다.
  • 균일한 분포: 적절한 구현을 사용하면 modulo bias를 제거할 수 있습니다.
  • 표준 지원: 모든 최신 브라우저(Chrome, Firefox, Safari, Edge)에서 지원합니다.
  • 빠른 속도: 시스템 수준에서 최적화되어 있어 실용적인 속도를 제공합니다.

QuickToolkit의 랜덤 뽑기 도구는 바로 이 crypto.getRandomValues() API를 기반으로 구현되어 있어, 공정하고 예측 불가능한 결과를 보장합니다.


일상에서의 랜덤 뽑기 활용

무작위 선택은 생각보다 훨씬 다양한 상황에서 활용됩니다.

1. 추첨 및 당첨자 선정

이벤트 당첨자 선정, 경품 추첨, 반 배정 등에서 공정한 무작위 선택은 필수입니다. 참여자 목록을 입력하고 원하는 수만큼 뽑으면 누구도 이의를 제기할 수 없는 투명한 결과를 얻을 수 있습니다. 특히 여러 명을 동시에 뽑아야 할 때 중복 허용/불허 옵션이 유용합니다.

2. 순서 정하기

발표 순서, 게임 순서, 당번 순서를 정할 때 가위바위보 대신 한 번에 모든 사람의 순서를 확정할 수 있습니다. 순서 섞기(셔플) 기능을 사용하면 전체 참여자의 순서가 한 번에 결정되어 시간도 절약하고 분쟁도 방지할 수 있습니다.

3. 팀 나누기

체육 시간, 프로젝트 조편성, 팀 빌딩 활동에서 팀을 나눌 때 편향 없이 공정하게 배분하는 것이 중요합니다. 무작위 팀 나누기는 친분이나 실력에 의한 편향을 제거하여 모두가 납득할 수 있는 결과를 만들어냅니다. 인원이 팀 수로 정확히 나누어지지 않더라도 자동으로 최대 1명 차이로 균등 배분됩니다.

4. 메뉴 및 장소 선택

“오늘 뭐 먹지?” 이 질문에 매일 답하기 어렵다면 후보 메뉴를 입력하고 랜덤으로 하나를 뽑아보세요. 여행지, 영화, 운동 종목 등 선택 장애가 올 때마다 무작위 뽑기가 결정을 도와줍니다. 결정 피로(decision fatigue)를 줄여주는 실용적인 방법입니다.

5. 교육 및 학습

교실에서 발표자 지명, 퀴즈 출제 순서, 좌석 배치 등에 활용할 수 있습니다. 교사가 임의로 학생을 선택하면 편향 의심을 받을 수 있지만, 투명한 무작위 도구를 사용하면 그런 우려를 해소할 수 있습니다.


공정한 추첨을 위한 조건

무작위 추첨이 진정으로 공정하려면 다음 조건들을 충족해야 합니다:

1. 균일한 확률 분포

모든 항목이 선택될 확률이 정확히 동일해야 합니다. 10명 중 1명을 뽑을 때 각각 정확히 10%의 확률을 가져야 합니다. 구현 방식에 따라 미세한 편향이 발생할 수 있으므로, modulo bias가 없는 알고리즘을 사용하는 것이 중요합니다.

2. 예측 불가능성

이전 결과로 다음 결과를 예측할 수 없어야 합니다. Math.random()과 같은 PRNG는 이 조건을 완벽히 충족하지 못하며, crypto.getRandomValues()와 같은 CSPRNG를 사용해야 합니다.

3. 재현 불가능성

같은 조건에서 다시 추첨해도 같은 결과가 나올 보장이 없어야 합니다. 시드 고정 방식의 PRNG는 이 조건을 위반합니다.

4. 투명성

추첨 과정이 참여자들에게 공개되어야 합니다. 어떤 알고리즘을 사용하는지, 모든 항목이 올바르게 입력되었는지 확인할 수 있어야 신뢰도가 높아집니다.

5. 클라이언트 처리

데이터가 외부 서버로 전송되지 않아야 조작 가능성을 원천 차단할 수 있습니다. 브라우저 내에서 모든 처리가 이루어지면 중간자 개입의 여지가 없습니다.


QuickToolkit 랜덤 뽑기 도구 소개

QuickToolkit의 랜덤 뽑기 도구는 위에서 설명한 모든 공정성 조건을 충족하도록 설계되었습니다.

주요 기능

  • 뽑기: 입력한 항목 중 원하는 개수만큼 무작위 선택합니다. 중복 허용/불허를 선택할 수 있고, 뽑기 기록이 세션 내에서 유지되어 이전 결과를 확인할 수 있습니다.
  • 순서 섞기: Fisher-Yates 셔플 알고리즘을 사용하여 모든 항목의 순서를 완전히 무작위로 재배열합니다. 이 알고리즘은 수학적으로 증명된 균일한 순열을 생성합니다.
  • 팀 나누기: 항목을 원하는 팀 수로 균등하게 나눕니다. 라운드 로빈 방식으로 배분하여 팀 간 인원 차이가 최대 1명을 넘지 않습니다.

기술적 특징

  • crypto.getRandomValues() 기반 암호학적 난수 사용
  • 100% 클라이언트 사이드 처리 (서버 전송 없음)
  • Fisher-Yates 셔플 알고리즘으로 균일한 분포 보장
  • 모바일 친화적 반응형 디자인

항목을 줄바꿈으로 입력하고 버튼 하나만 누르면 됩니다. 복잡한 설정 없이 누구나 쉽게 사용할 수 있으며, 결과를 복사하여 메신저나 문서에 바로 붙여넣을 수 있습니다. 지금 바로 랜덤 뽑기 도구를 사용해보세요.