직접 실험·검증한 가이드
작성 paper&honey 운영자 게시 수정
zip 파일 한글 이름이 깨지는 이유 — 자소 분리와 인코딩
zip 파일을 주고받다가 한글 파일 이름이 깨지는 문제는 사실 하나가 아니라 두 가지 별개의 문제입니다. 하나는 "한글.txt"가 "ㅎㅏㄴㄱㅡㄹ.txt"처럼 낱자로 풀어지는 자소 분리이고, 다른 하나는 이름이 아예 읽을 수 없는 문자로 바뀌는 인코딩 깨짐입니다. 겉보기에는 비슷해 보여도 원인이 다르기 때문에, 어느 쪽 증상인지 구분해야 올바른 해결책을 고를 수 있습니다.
증상 1 — 자소 분리는 유니코드 정규화 차이입니다
유니코드에서 "한"이라는 글자는 두 가지 방식으로 표현할 수 있습니다. 완성된 글자 하나로 저장하는 방식을 NFC(완성형), ㅎ·ㅏ·ㄴ 세 낱자를 결합해 저장하는 방식을 NFD(조합형)라고 부릅니다. 화면에 표시될 때는 둘 다 "한"으로 보이지만, 내부 데이터는 서로 다릅니다.
맥(macOS)에서는 파일 이름이 NFD로 저장되는 경우가 많고, 윈도우와 대부분의 다른 환경은 NFC를 기대합니다. 다만 맥이 언제나 NFD로 저장하는 것은 아닙니다. 지금의 APFS는 정규화를 강제하지 않아서, 이름을 만든 주체가 Finder냐 터미널이냐에 따라 같은 디스크에서도 NFD와 NFC가 갈립니다. 그 실측은 맥 자소분리 실측 가이드에 정리해 두었습니다. 그래서 NFD로 만들어진 이름을 맥에서 zip으로 압축하면 압축 파일 안에 NFD 형태가 그대로 기록되고, 이 파일을 윈도우에서 풀면 낱자를 결합해 주지 않아 "ㅎㅏㄴㄱㅡㄹ"처럼 분리된 채로 표시됩니다. 글자를 읽을 수는 있지만 검색이 안 되고, 같은 이름의 파일과 다른 파일로 취급되는 문제가 생깁니다. 예를 들어 탐색기에서 "한글"로 검색해도 분리된 "ㅎㅏㄴㄱㅡㄹ" 이름은 걸리지 않고, 프로그램에서 완성형 경로로 파일을 지정하면 같은 이름인데도 찾지 못합니다.
증상 2 — 외계어 깨짐은 문자 인코딩 차이입니다
zip 포맷은 원래 파일 이름을 어떤 인코딩으로 기록했는지 담는 표준이 없었습니다. 그래서 압축 프로그램들은 각자 시스템의 기본 인코딩으로 이름을 기록해 왔습니다. 한국어 윈도우 환경은 CP949(EUC-KR 계열)를, 맥과 리눅스는 UTF-8을 기본으로 씁니다.
CP949로 기록된 zip을 UTF-8을 기대하는 환경에서 열면, 같은 바이트를 다른 문자로 해석하기 때문에 이름이 전혀 읽을 수 없는 기호의 나열로 바뀝니다. 이후 zip 규격에 파일 이름이 UTF-8이라고 표시하는 플래그가 추가되긴 했지만, 모든 압축 프로그램이 이 플래그를 기록하거나 읽는 것은 아니어서 지금도 호환 문제가 남아 있습니다.
CP949 파일명 zip을 직접 만들어 봤습니다
말로만 "바이트가 다르게 해석된다"고 하면 잘 와닿지 않아서, 한국어 윈도우 환경이 만드는 구조를 모사해 CP949로 파일명을 기록한 zip을 직접 만들어 헤더를 열어봤습니다. 입력은 파일명 "한글보고서.txt" 하나이고, 도구는 파이썬 3.14.5 표준 라이브러리 zipfile(macOS 26.5.2)입니다. 파이썬 zipfile은 한글 파일명을 무조건 UTF-8로 적고 UTF-8 플래그(비트 11)를 켜서 기록하기 때문에, 그대로는 CP949 zip을 만들 수 없습니다. 그래서 만들어진 zip의 로컬 헤더와 중앙 헤더에서 파일명 바이트를 CP949로 바꾸고, 파일명 길이 필드와 비트 11, 그리고 마지막 EOCD의 중앙 디렉터리 크기·오프셋을 손으로 고쳐 넣었습니다. 판독은 두 헤더의 파일명 필드를 16진수로 덤프하고, 다시 zipfile로 열어 이름이 어떻게 읽히는지 확인하는 순서로 했습니다.
utf-8 bytes : 19 ed 95 9c ea b8 80 eb b3 b4 ea b3 a0 ec 84 9c 2e 74 78 74
cp949 bytes : 14 c7 d1 b1 db ba b8 b0 ed bc ad 2e 74 78 74
local header filename : c7 d1 b1 db ba b8 b0 ed bc ad 2e 74 78 74
central header filename: c7 d1 b1 db ba b8 b0 ed bc ad 2e 74 78 74
local bit11 : False
central bit11: False
zipfile.filename (cp437 오해석): '╟╤▒█║╕░φ╝¡.txt'
raw bytes : c7 d1 b1 db ba b8 b0 ed bc ad 2e 74 78 74
cp949 복원 : '한글보고서.txt'
utf-8 엄격 해석 : UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc7 in position 0: invalid continuation byte 같은 이름인데 UTF-8로 적으면 19바이트, CP949로 적으면 14바이트입니다. 완성형 인코딩에서 한글 한 글자가 2바이트라 그렇습니다. 이 zip을 열면 UTF-8 플래그가 꺼져 있으므로, zip 규격의 기본 해석을 따르는 프로그램(파이썬 zipfile 등)은 기본값인 CP437로 이름을 해석합니다. 그 결과가 ╟╤▒█║╕░φ╝¡.txt입니다 — 흔히 말하는 "외계어"의 정체가 이것입니다. 같은 바이트를 CP949로 다시 읽으면 "한글보고서.txt"가 그대로 돌아옵니다. 이름이 손상된 것이 아니라 해석 규칙만 어긋나 있었다는 뜻입니다. 한 가지 덧붙이면, 이 바이트를 UTF-8로 엄격하게 해석하면 깨진 글자가 나오는 것이 아니라 아예 오류가 납니다. 위 출력의 마지막 줄이 그것으로, 0xc7 뒤에는 UTF-8 규칙상 연속 바이트가 와야 하는데 다음 바이트(0xd1)가 연속 바이트가 아니라서 해석이 중단됩니다. 그래서 프로그램에 따라 이름이 이상하게 보이는 대신 압축 해제 자체가 실패하기도 합니다.
어떤 조합에서 어떤 증상이 나오나
- 맥에서 압축 → 윈도우에서 열기. 대개는 이름이 읽히되 "ㅎㅏㄴㄱㅡㄹ"처럼 자소가 분리됩니다. 다만 맥 기본 압축은 이름을 UTF-8 바이트로 적으면서도 UTF-8 플래그는 켜주지 않아, 여는 프로그램에 따라서는 자소 분리를 넘어 외계어 깨짐까지 갈 여지가 남습니다(실측).
- 윈도우에서 CP949로 압축 → 맥에서 열기. 이름이 읽을 수 없는 문자로 깨지거나, 압축 해제 자체가 실패하기도 합니다.
- 윈도우에서 CP949로 압축 → 리눅스·NAS에서 열기. 마찬가지로 UTF-8을 기대하는 환경이라 이름이 깨집니다.
- 같은 운영체제끼리 주고받기. 인코딩과 정규화 방식이 같으므로 대체로 문제가 없습니다.
예방법 — 만들 때부터 깨지지 않게
윈도우에서 맥·리눅스 사용자에게 보낼 때는, 파일 이름을 UTF-8로 기록하는 옵션이 있는 압축 프로그램을 쓰는 것이 안전합니다. 반디집처럼 압축 시 파일명 인코딩을 선택할 수 있는 프로그램이라면 UTF-8을 지정해 주면 됩니다.
맥에서 윈도우 사용자에게 보낼 때는 자소 분리가 문제이므로, 받는 쪽에서 분리된 자소를 자동으로 결합해 표시해 주는 압축 프로그램으로 열도록 안내하는 방법이 있습니다. 받는 사람의 환경을 알 수 없다면, 중요한 서류는 zip으로 묶지 않고 파일을 하나씩 첨부하는 것도 인코딩 문제를 원천적으로 피하는 방법입니다. 가장 확실한 예방법은 다소 원시적이지만, 여러 환경을 오가는 파일이라면 이름을 영문과 숫자로만 짓는 것입니다. 자소 분리와 인코딩 문제 모두 한글 이름에서만 발생하기 때문입니다.
이미 깨진 zip을 받았다면
이미 이름이 깨진 채로 zip을 받았다면 보낸 사람에게 다시 압축해 달라고 하기보다, 받은 쪽에서 인코딩을 바로잡아 푸는 편이 빠릅니다. paper&honey의 zip 한글 깨짐 복구 도구에 파일을 올리면 브라우저 안에서 파일 이름 인코딩을 해석해 원래 한글 이름으로 압축을 풀 수 있습니다. 모든 작업은 사용자 기기 안에서 끝나고 파일이 인터넷으로 오가지 않으므로, 업무 문서처럼 민감한 파일에도 안심하고 쓸 수 있습니다. 단, 이름이 아니라 압축이 아예 시작도 안 되는 경우라면 원인이 다릅니다. 맥에서 "오류 79"가 뜨며 거부당한다면 파일명이 아니라 압축 방식 자체가 문제인데, 그 사례는 맥 압축 오류 79 실측 가이드에서 파일을 뜯어 확인했습니다.
자주 묻는 질문
Q. 맥에서는 파일 이름이 멀쩡해 보이는데 왜 깨져서 전달되나요? NFD로 저장된 이름도 맥 화면에서는 정상적인 "한글"로 표시됩니다. 겉모습은 같지만 내부 데이터가 낱자로 나뉘어 있고, 이 데이터가 zip에 그대로 담겨 윈도우로 넘어가면서 분리된 형태가 드러나는 것입니다.
Q. NFD는 잘못된 방식인가요? 아닙니다. NFC와 NFD 모두 유니코드 표준이 허용하는 정규화 방식입니다. 다만 어느 쪽으로 이름을 만드는지가 운영체제와 앱마다 다르고, 심지어 같은 맥 안에서도 Finder와 터미널이 갈리기 때문에, 서로 다른 환경 사이에서 파일을 주고받을 때 호환 문제가 생기는 것입니다.
Q. 압축 프로그램만 바꾸면 항상 해결되나요? 항상은 아닙니다. 인코딩 깨짐은 UTF-8 옵션이 있는 프로그램으로 만들면 대부분 예방되지만, 자소 분리는 여는 쪽 프로그램의 결합 처리 여부에도 달려 있습니다. 보내는 쪽과 받는 쪽 중 한쪽만 통제할 수 있다면, 위의 조합별 증상을 보고 자신이 통제할 수 있는 쪽에서 대응하는 것이 현실적입니다.