7장. EUC-KR, 완성형과 조합형 — 한국의 선택

만화로 보는 요약 — 먼저 읽어보세요
EUC-KR의 완성형은 미리 넣은 음절을 빠르게 찾는 대신 2,350자만 담았고, 모든 음절을 조립하는 조합형과의 선택은 한글 인코딩의 오래된 트레이드오프가 됐다.
면접 실전 질문: ① 완성형과 조합형의 차이는? ② EUC-KR이 모든 한글을 담지 못한 이유는? ③ 2,350자 제한은 어떤 문제를 만들었는가?
배경 — 한글은 조립되는 글자다
6장에서 2바이트라는 넓은 방이 생겼습니다. 이제 한국 차례예요. 그런데 한글에는 알파벳이나
한자에 없는 독특한 성질이 있습니다. 자음과 모음을 조립해서 글자를 만든다는 거죠.
강은 그냥 통짜 그림이 아니라 ㄱ + ㅏ + ㅇ의 조합이에요.
그래서 한글을 코드에 담을 때 근본적으로 다른 두 갈래 길이 열립니다.
- 완성된 음절을 통째로 표에 넣기.
가,나,강,힣… 이미 조립된 음절 하나하나에 코드 번호를 매긴다. 사전에 단어를 싣듯이요. - 자음·모음 조각을 코드로 만들어 조립하기.
ㄱ,ㅏ,ㅇ에 각각 번호를 주고, 읽을 때 조립해서강을 만들어낸다. 한글 창제 원리 그대로요.
전자를 완성형, 후자를 조합형이라고 부릅니다. 한국은 이 두 길에서 하나를 골라야 했어요.
스토리 — 두 철학의 대결
완성형은 직관적이었어요. 음절 가에 번호 하나, 각에 번호 하나. 글자를 읽고 쓰는 게
그냥 표 찾기(lookup)라서 처리가 단순하고, 정렬이나 검색도 깔끔했죠. 한국은 이 완성형을
국가 표준(KS C 5601, 지금의 KS X 1001)으로 채택합니다. 그리고 이 표준 문자를 6장의 2바이트
방식으로 실어 나르는 인코딩이 바로 EUC-KR이에요.
조합형은 영리한 발상이었습니다. 2바이트 = 16비트를 잘게 쪼개서, 앞부터 초성·중성· 종성 자리에 각각 자모 번호를 비트로 박아 넣는 거예요. 한글이 원래 조립되는 글자니까, 코드도 조립식으로 만들자는 거죠. 덕분에 한글 음절이라면 무엇이든 2바이트로 표현할 수 있었어요.
하지만 조합형에도 대가가 있었습니다. 자모를 비트로 욱여넣다 보니, 2번째 바이트가 ASCII
영역과 겹치는 경우가 생겼거든요. 실제로 가를 조합형으로 찍으면 두 번째 바이트가 하필
0x61, 알파벳 a와 똑같습니다. 6장에서 자랑한 그 깔끔한 ‘선행 바이트’ 규칙이 깨지는
지점이에요 — 9장에서 만날 Shift-JIS와 정확히 같은 병입니다. 조합형도 훗날 표준의 한
갈래(부속서)로 인정받았지만, 주류 자리는 완성형이 가져갔어요.
해피엔딩 같죠? 여기서부터가 진짜입니다. 이 선택이 한국 개발자와 사용자를 두고두고 괴롭히는 문제를 낳거든요.
핵심 — 2,350자라는 감옥
완성형의 치명적 한계는 표에 넣은 음절만 쓸 수 있다는 거예요. 그런데 KS 완성형이 표에 넣은 한글은 딱 2,350자였습니다. “자주 쓰는 것만” 골라 담은 거죠.
문제는 한글로 조합 가능한 음절이 11,172자(초성 19 × 중성 21 × 종성 28, 받침 없음
포함)라는 겁니다.
2,350자는 그중 21%에 불과해요. 나머지 8,822자는 표에 아예 없었습니다. 뷁, 똠,
펲 같은 음절이요. 바이트로 직접 보면 이 한계가 적나라하게 드러납니다.
print("가".encode("euc-kr")) # b'\xb0\xa1' ← 완성형 2,350자, 2바이트로 깔끔
print("뷁".encode("euc-kr")) # b'\xa4\xd4\xa4\xb2\xa4\xce\xa4\xaa' ← 표에 없어 8바이트 편법!
print("뷁".encode("johab")) # b'\xa6\xca' ← 조합형은 자모를 조립, 2바이트로 거뜬가는 2,350자 안에 있어서 2바이트로 딱 떨어져요. 그런데 뷁은 표에 없어서, EUC-KR은
채움 문자(filler) 하나에 초성·중성·종성 자모를 붙여 무려 4칸, 8바이트로 겨우
표현합니다(채움 + 자모 3개 = 4칸 × 2바이트). 이마저도 제대로 지원하는 시스템이 드물어서,
현실에선 아예 못 쓰는 글자 취급이었어요. 반면 조합형은 같은 뷁을 자모 조립으로
2바이트에 거뜬히 담습니다.
이게 단순한 이론 문제가 아니었어요. 실제로 90년대 한국에선 이름이나 상표에 완성형에 없는 음절이 들어가면 컴퓨터에 입력조차 안 되는 일이 벌어졌습니다. 기술 표준의 선택이 사람들의 일상을 제약한 거예요.
완성형 대 조합형은 결국 인코딩 설계의 두 철학 — ‘통째로 외우기(lookup)’ vs ‘규칙으로 조립하기’ — 이 부딪힌 사건이었어요. 그리고 완성형이 표준이 된 이상, 남은 문제는 분명했습니다. 비어 있는 8,822자를 어떻게든 메워야 한다.
정리
- 한글은 자음·모음을 조립하는 글자라, 코드화에 두 길이 있었다: 음절을 통째로 표에 넣는 완성형(KS X 1001 → EUC-KR) vs 자모를 비트로 조립하는 조합형.
- 한국은 처리가 단순한 완성형을 국가 표준으로 택했다. 하지만 완성형은 2,350자만
담아서, 한글 음절 11,172자 중 79%가 누락됐다(
뷁·똠·펲…). - 코드로 확인:
가는 EUC-KR 2바이트지만, 표에 없는뷁은 8바이트 편법(사실상 사용 불가) → 같은 글자를 조합형은 2바이트로 표현. 담은 만큼만 쓰는 완성형의 한계. - 교훈: 완성형(외우기) vs 조합형(조립)은 설계 철학의 대립이었다. 조합형이 모든 음절을 담고도 주류가 못 된 건 이미 표준·기득권을 쥔 완성형을 뒤집기 어려웠기 때문이고, 조합형 역시 ASCII 충돌이라는 대가가 있었다 — 어느 쪽도 공짜가 아니었다.
생각해볼 질문: 완성형은 이미 국가 표준으로 자리 잡았고 수많은 문서·시스템이 거기 맞춰 돌아가고 있었어요. 이제 와서 표준을 조합형으로 갈아엎을 순 없습니다. 그럼 비어 있는 8,822자는 어떻게 채울까요? 정답을 새로 만드는 대신, 누군가 기존 완성형은 그대로 두고 빈 공간에 나머지 음절을 우겨넣는 현실적인 확장을 시도합니다. 그 주인공은 뜻밖에도 마이크로소프트였어요.