25년 만에 풀린 미스터리: 윈도우 XP 프로필 사진은 제비뽑기가 아닌 부팅 시간의 결과였다

25년 만에 풀린 미스터리: 윈도우 XP 프로필 사진은 제비뽑기가 아닌 부팅 시간의 결과였다

Windows XP역사

데이터 소스:HN + web research

전 세계 수억 명의 사용자들은 윈도우 XP를 처음 부팅할 때 할당되는 기본 프로필 사진이 순수한 무작위 추출이라고 여겨왔다. 2026년 9월 9일, 마이크로소프트의 베테랑 엔지니어 레이먼드 첸(Raymond Chen)이 코드 한 편을 공개하며 25년 동안 시스템 깊은 곳에 숨겨져 있던 로직을 세상에 알렸다. 얼핏 운에 맡긴 것처럼 보였던 첫 프로필 사진은 제비뽑기가 아니라, 정확하게 계산된 수학적 결과물이었다.

트윗 한 줄이 촉발한 코드 고고학

2025년 12월 11일, 제노(Xeno)라는 닉네임의 사용자가 트위터에서 질문을 던졌다. 윈도우 XP가 계정을 처음 생성할 때 어떤 난수 생성 알고리즘을 사용해 프로필 사진을 결정하는지 궁금하다는 내용이었다. 이는 개발자 커뮤니티에서 20년 넘게 해소되지 않았던 의문이었다. 레이먼드 첸은 일찍이 2004년 4월 자신의 블로그 글에서 XP 프로필 사진이 무작위로 선택된다고 가볍게 언급한 적이 있었다. 그러나 그런 개략적인 설명은 호기심 많은 엔지니어들을 납득시키지 못했다. 그들이 원한 것은 두루뭉술한 결론이 아니라 구체적인 코드와 알고리즘의 유도 과정이었다.

레이먼드 첸은 결국 자신의 블로그 ‘디 올드 뉴 씽(The Old New Thing)‘을 통해 실제 코드 로직을 공개했다. 이 글은 해커뉴스(Hacker News)에서 단숨에 333점의 추천과 162개의 댓글을 기록하며 뜨거운 관심을 모았다. 당시 사용자 화면에 나타났던 기타, 꽃, 체스 말, 오리 인형 등은 암흑 속 상자에서 무작위로 집어 든 것이 아니었다. 그 이면에는 치밀하게 계산된 수학적 절차가 자리 잡고 있었다.

초기 시드는 부팅 후 경과 밀리초

윈도우 XP의 기본 프로필 사진 파일들은 시스템의 깊숙한 폴더에 보관되어 있었다. 구체적인 경로는 %ALLUSERSPROFILE%\Application Data\Microsoft\User Account Pictures\Default Pictures였다. 시스템은 새 계정을 만들 때마다 이 디렉터리 안에서 사진 하나를 골라내야 했다.

핵심 호출 대상은 윈도우 내부에 내장된 RtlRandomEx 의사 난수 생성기였다. 모든 의사 난수 알고리즘은 초기 시드(Seed)를 필요로 한다. 마이크로소프트 엔지니어들은 복잡한 하드웨어 엔트로피를 가져다 쓰는 대신 GetTickCount()의 반환값을 시드로 넘겼다. 이 함수는 시스템이 부팅된 순간부터 현재 시점까지 경과한 시간을 정확한 밀리초 단위로 반환한다.

의사 난수 알고리즘은 입력 조건이 명확하다. 즉, 컴퓨터가 부팅되는 데 걸린 밀리초를 정확하게 기록해 두기만 하면 어떤 사진이 나올지 완벽하게 역산할 수 있었다. 사용자 입장에서는 예측할 수 없는 우연처럼 느껴졌지만, 코드 레벨에서는 철저히 결정론적인 과정이었던 셈이다.

저수지 샘플링으로 순회를 1회로 단축

파일 개수를 미리 알 수 없는 디렉터리를 다룰 때 교과서적인 방식은 2회 순회(Two-pass)다. 먼저 폴더 전체를 훑으며 전체 파일 수 n을 세고, 1부터 n 사이의 난수 인덱스를 생성한 뒤, 다시 처음부터 순회해 해당 위치의 파일을 가져오는 방식이다. 전형적인 나이브 알고리즘이다.

마이크로소프트 엔지니어들은 이 방식을 택하지 않았다. 그들은 단일 순회(Single-pass) 알고리즘을 사용했다. 디렉터리를 스캔하는 동안 시스템은 카운터 count와 현재 당첨된 항목인 winner라는 두 개의 변수만 유지한다. 항목을 하나 읽을 때마다 count를 1씩 증가시키고, 1/count의 확률로 winner를 방금 읽은 사진으로 교체할지 결정한다. 디렉터리 탐색이 끝났을 때 마지막까지 winner에 남아 있는 사진이 최종 결과가 된다.

selectRandomFromIterator 단일 순회 알고리즘 코드 그림: selectRandomFromIterator 단일 순회 알고리즘 코드. 출처: The Old New Thing

이는 k=1일 때의 고전적인 저수지 샘플링(Reservoir Sampling) 특수 사례다. n개의 항목이 있을 때 마지막 파일이 선택될 확률은 정확히 1/n이다. 마지막 파일이 선택되지 않는다면, 문제는 앞선 n-1개 파일 중에서 동일하게 균일 선택하는 재귀 구조로 환원된다. 폴더에 파일이 몇 개 들어 있든 간에 모든 파일이 최종적으로 선택될 확률은 균등하게 1/n로 유지된다.

파일 시스템 I/O와 타협한 수학 이론

왜 단순명료한 2회 순회를 버리고 저수지 샘플링을 선택했을까? 그 해답은 운영체제의 근본적인 병목 지점에 있었다. 계정 생성 단계에서 파일 시스템 호출 오버헤드는 단순 CPU 연산 비용보다 훨씬 컸다. 특히 초기 시절의 기계식 하드디스크는 수많은 작은 파일을 반복해서 순회할 때 심각한 속도 저하를 겪었다.

단일 순회 방식은 파일 시스템 호출 시간을 대폭 단축했다. 나아가 디렉터리 내 파일이 연산 도중에 변경되더라도 오류 없이 안전하게 실행되었다.

2회 순회 방식은 첫 번째 검사와 두 번째 추출 사이에 파일 총개수가 완전히 동일하게 유지되어야 한다. 만약 숫자를 세는 작업과 값을 읽어오는 찰나의 순간에 다른 프로세스가 사진 폴더를 건드린다면, 인덱스 범위를 벗어나거나 파일을 찾지 못해 시스템 충돌이 일어날 수 있다. 단일 순회 메커니즘은 이 타이밍에 발생할 수 있는 동시성 위험을 원천적으로 차단했다.

100장 스캔 즉시 중단되는 안전장치

저수지 샘플링은 수학적으로 무한한 입력 스트림에서도 우아하게 동작한다. 카운터가 커질수록 현재 쥔 패가 바뀔 확률은 정비례하여 줄어든다. 그러나 실제 운영체제 코드는 무한 루프를 결코 용납하지 않는다. 엔지니어들은 이 핵심 로직에 실용적이고 직관적인 안전장치를 하드코딩해 두었다.

샘플링한 사진 수가 100장에 도달하면 알고리즘은 즉시 반복문을 강제로 탈출하여 현재 들고 있는 사진을 곧바로 반환한다.

윈도우 XP 기본 루나 인터페이스 그림: 윈도우 XP 기본 루나 인터페이스. 출처: Wikipedia

현장의 시스템 엔지니어들은 순수 수학의 이상론에 얽매이지 않는다. 100장이라는 물리적 상한선을 둔 이유는 혹시라도 누군가 폴더에 수백만 개의 파일을 집어넣어 부팅 과정 전체를 멈추게 만드는 비정상적 상황을 방지하기 위함이었다. 수학적 모델은 무한한 모집단에 대한 균일 분포를 지향하지만, 상용 코드의 최우선 책무는 시스템이 결코 다운되지 않도록 보장하는 것이다.

우연이라는 착각 뒤에 숨겨진 정밀한 계산

다시 트위터의 원래 질문으로 돌아가 보자. 2001년부터 2014년까지 수많은 사람들이 윈도우 XP를 처음 켜던 순간의 설렘을 기억하고 있다. 모니터에 뜬 축구공, 오리, 개구리를 보며 사람들은 운영체제가 우연히 건넨 깜짝 선물이라고 믿었다. 일반 사용자는 부팅 과정에서 일어나는 미세한 시간 차이를 감지할 수 없다. 불과 몇 밀리초의 오차가 그들의 눈에는 완벽한 무작위로 비쳤던 것이다.

레이먼드 첸의 글은 오랫동안 묻혀 있던 의문을 풀어주었을 뿐 아니라, 당시의 소프트웨어 공학 풍경을 고스란히 담아낸 스냅샷이기도 하다. 메모리는 작았고 하드디스크는 느렸다. 코드 한 줄마다 철저한 계산이 필요했고, 모든 예외 상황마다 방어적 프로그래밍이 요구되었다.

25년 전 그 무작위처럼 보였던 기본 이미지는 아무렇게나 뽑은 제비가 아니었다. 엄격한 파일 상한선과 정교한 샘플링 로직을 통해 두 세대의 사용자에게 전달된 정밀한 계산의 산물이었다.

참고 링크:

  • The Old New Thing
  • HN
  • Wikipedia