TXT 파일에서 한글이 깨질 때: EUC-KR과 CP949
.txt 파일을 열었는데 한글 대신 알 수 없는 기호가 늘어서 있습니다. 파일이 망가진 것이 아닙니다. 바이트는 전부 그대로 있고, 잘못된 대조표로 읽히고 있을 뿐입니다.
왜 이런 일이 생기나
일반 텍스트 파일은 자기가 어떤 인코딩인지 파일 안에 적어 두지 않습니다. 그저 바이트의 나열이고, 해석은 여는 프로그램이 정합니다.
한국어 옛 파일은 대개 EUC-KR이거나 CP949입니다. 개인이 정리한 텍스트, 옛 게시판에서 내려받은 자료, 예전 워드프로세서에서 내보낸 파일이 여기에 해당합니다.
EUC-KR과 CP949는 왜 나뉘어 있나
이 둘의 관계가 한국어 인코딩 문제를 다른 언어와 다르게 만듭니다.
한글은 초성, 중성, 종성을 조합해 이론상 11,172자의 음절을 만들 수 있습니다. 그런데 EUC-KR의 바탕인 KS X 1001에는 그중 2,350자만 들어 있습니다. 실제로 자주 쓰이는 글자만 골라 넣은 것입니다.
그래서 EUC-KR로는 “똠”, “뷁”, “믜” 같은 글자를 아예 표현할 수 없습니다. 의성어와 의태어, 방언, 새로 만든 말, 외국 이름을 옮긴 표기에서 이 한계가 드러납니다.
CP949는 여기에 8,822자를 더해 11,172자를 모두 담습니다. 확장 부분의 바이트 배열이 EUC-KR 규칙에서 벗어나 있어서, EUC-KR로 열면 흔한 글자는 멀쩡한데 드문 글자만 깨지는 상태가 됩니다.
| 인코딩 | 한글 음절 수 | 흔한 출처 |
|---|---|---|
| UTF-8 | 전부 | 현재 표준 |
| CP949 | 11,172 | 윈도우에서 저장한 한국어 파일 |
| EUC-KR | 2,350 | 더 오래된 자료, 초기 웹 |
| UTF-16 | 전부 | 일부 윈도우 프로그램의 내보내기 |
깨짐의 모양으로 원인 좁히기
증상이 세 가지로 갈립니다.
전부 깨진다면 인코딩을 통째로 잘못 짚은 것입니다. 한글은 두 바이트로 표현되고 두 바이트 모두 최상위 비트가 1이라, 이것을 Latin-1로 읽으면 한 글자가 악센트 붙은 라틴 기호 두 개로 바뀝니다. 화면의 글자 수가 원문의 두 배쯤으로 늘어나 보입니다.
대부분 멀쩡한데 드문 글자만 깨진다면 CP949 파일을 EUC-KR로 읽은 것입니다. 확장 영역에 있는 글자만 무너집니다.
본문은 멀쩡한데 파일 이름이 깨진다면 원인이 다릅니다. 아래에서 따로 다룹니다.
앱의 현재 동작
분명히 적어 두는 편이 낫겠습니다. Aurora Reader는 UTF-8을 먼저 시도하고, 실패하면 Latin-1로 되돌아갑니다. EUC-KR도 CP949도 알아보지 못하고, 설정에 인코딩을 고르는 항목도 없습니다.
Latin-1은 왜 오류 메시지 대신 깨진 글자가 보이는지도 설명해 줍니다. 그 인코딩에서는 어떤 바이트든 대응하는 기호가 있어서, 되돌아가는 경로가 언제나 “성공”합니다. 다만 틀린 글자를 내놓을 뿐입니다.
이 동작은 문제로 기록해 두었습니다.
고치는 법
컴퓨터에서 사본을 변환한 뒤 폰으로 다시 옮깁니다.
iconv -f CP949 -t UTF-8 book.txt > book-utf8.txt
-f EUC-KR보다 -f CP949를 먼저 시도하십시오. CP949는 EUC-KR을 포함하므로 EUC-KR 파일도 올바로 읽지만, 반대는 성립하지 않습니다. 드문 글자에서 변환이 멈춘다면 원본이 CP949인데 EUC-KR로 지정한 경우입니다.
윈도우라면 메모장에서 열고 다시 저장하며 인코딩을 UTF-8로 지정해도 됩니다. 파일이 크면 느립니다.
항상 사본으로 작업하십시오. 인코딩을 잘못 지정한 변환은 되돌릴 수 없습니다.
압축 파일에서 이름이 깨질 때
본문은 멀쩡한데 파일 이름만 깨지는 경우가 있습니다. 이것은 별개의 문제입니다.
ZIP 형식은 오랫동안 파일 이름의 인코딩을 규정하지 않았습니다. 윈도우에서 만든 압축 파일은 이름을 CP949로 적어 두는데, 안드로이드의 압축 해제 도구는 대개 UTF-8로 읽습니다. 그래서 안의 텍스트는 정상인데 이름만 무너집니다.
내용이 멀쩡하다면 이름을 직접 고쳐 쓰는 것이 가장 빠릅니다. 권수가 많으면 컴퓨터에서 인코딩을 지정할 수 있는 압축 프로그램으로 풀고 나서 폰으로 옮기십시오.
목차가 잡히지 않는 것은 다른 문제
글자는 멀쩡한데 목차가 비어 있는 경우가 있습니다.
이것은 인코딩과 무관합니다. 앱이 장을 찾을 때 맞춰 보는 것은 Chapter 1, Part 2 같은 영어 표기여서, “제1장”이나 “1화”는 걸리지 않습니다. 같은 코드가 단어 수를 공백으로 세기 때문에 쪽수 추정도 함께 어긋납니다. 두 가지 모두 장 인식과 단어 수 계산 문제로 등록해 두었습니다.
파일 손상과는 다릅니다
망가진 파일은 대개 아예 열리지 않거나 중간에 끊깁니다. 처음부터 끝까지 일정하게 틀린 글자가 나온다면 바이트는 온전합니다. 구분은 파일이 손상되었는지 판단하기에 있습니다.
확장자를 바꾸는 것은 소용이 없습니다. 확장자는 내용의 바이트와 아무 관계가 없습니다.
글자는 맞는데 모양이 이상하다면
인코딩도 손상도 아니고 글꼴 문제입니다. 옛 문헌에는 지금 쓰지 않는 자모가 섞여 있고, 현대 한글 음절만 담은 글꼴은 이것을 그리지 못해 빈 네모를 내놓습니다. 한자가 섞인 문헌도 마찬가지입니다.
해결은 글꼴을 직접 넣는 것입니다.
다시 겪지 않으려면
같은 책이 EPUB으로 있다면 그쪽을 받으십시오. EPUB은 인코딩을 파일 안에 선언하기 때문에 이 문제가 생기지 않습니다. 위키문헌의 EPUB 내보내기가 편리한 이유이기도 합니다.