회사에서 이벤트 경품 추첨이나 성과급 특별 지급 대상자 선정을 할 때, 공정한 랜덤 선발이 필요하다. 랜덤 숫자 생성기의 원리를 이해하고 실제 시스템에 어떻게 적용하는지 알아본다.
진짜 랜덤이란
컴퓨터에서 생성하는 난수는 대부분 의사 난수(Pseudo Random)다. 시드값을 기반으로 결정론적으로 생성되기 때문에, 시드를 알면 예측할 수 있다. 추첨에서는 이게 문제가 될 수 있다.
// 좋지 않은 예 - 시드가 시간이라 예측 가능 Math.random();
// 나은 예 - 암호학적 난수 crypto.getRandomValues(new Uint32Array(1))[0];
gogolink.kr/random-generator에서 랜덤 숫자를 생성해볼 수 있다.
추첨 시스템 설계
공정한 추첨 시스템의 핵심 요소다.
- 참가자 목록의 불변성: 추첨 전에 확정
- 난수 생성의 예측 불가능성: CSPRNG 사용
- 추첨 과정의 투명성: 로그 기록, 영상 녹화
- 결과의 검증 가능성: 시드와 알고리즘 공개
Fisher-Yates 셔플
N명 중 K명을 뽑을 때, 전체를 셔플하고 앞에서 K명을 선택하는 방법이 있다. Fisher-Yates 알고리즘으로 편향 없이 셔플한다.
function shuffle(array) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(secureRandom() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } return array; }
가중치 랜덤
성과에 따라 당첨 확률을 다르게 하고 싶을 때 가중치 랜덤을 쓴다. 성과 점수가 높을수록 가중치를 크게 주는 방식이다. 랜덤 생성 도구로는 구현이 어렵고, 별도 로직이 필요하다.
중복 당첨 방지
같은 사람이 여러 번 뽑히지 않도록 하려면, 당첨자를 제외하고 다음 추첨을 진행한다. 또는 처음부터 중복 없이 K명을 선택하는 알고리즘을 쓴다.
감사 로그
추첨 결과에 이의가 제기될 수 있으니, 전체 과정을 기록해야 한다. 참가자 목록, 시드값, 알고리즘 버전, 생성된 난수 시퀀스, 최종 당첨자를 모두 저장한다.
요약
추첨 시스템은 기술적 공정성과 절차적 투명성이 모두 필요하다. 간단한 랜덤 숫자가 필요할 때 온라인 랜덤 생성기를 활용할 수 있다.