ZIPで日本語ファイル名が文字化けする理由
Windowsで作ったZIPファイルを渡したら、相手の環境でファイル名だけが「テスト.txt」のような記号の羅列に化けていた——という経験がある人は少なくないはずです。この現象は偶然のバグではなく、ZIPの公式仕様PKWARE APPNOTE.TXTが定める汎用フラグのビット11(Language encoding flag/EFS)という1個のフラグの有無で説明できます。本記事は、原文の規定内容と、この環境のpythonでその因果関係を実際に再現した結果を並べ、7-Zip・RAR 5.0・MIMEのファイル名との違いも整理します。本サイトは特定のツールの文字化けの有無を判定するものではありません。
ZIPのファイル名エンコーディングを決める1ビット
出典はPKWARE APPNOTE.TXT Version 6.3.10(Revised Nov 01, 2022)の§4.4.4 general purpose bit flagとAPPENDIX Dです。汎用フラグのビット11(0x0800、Language encoding flag/EFSとも呼ばれます)が立っている場合、原文には次のようにあります。
MUST be encoded using UTF-8
一方、このビットが立っていない場合、APPENDIX Dは次のように定めています。
SHOULD conform to the original ZIP
ここで見落とせないのは、両者の義務の強さが非対称であることです。ビット11ありは「UTF-8でMUST(必須)エンコード」、ビット11なしは「従来のZIP文字エンコーディング(IBM Code Page 437)にSHOULD(努力目標であり必須ではない)準拠」とされています。つまりビット11が立っていないZIPのファイル名は、規格上は前提としてCP437として解釈される、という約束事になっています。
この環境のpythonで実機再現した4つの事実
規格の原文だけでなく、実際にファイルを作って読み戻す検証をこの環境のpython(3.13.3)で行いました。検証スクリプトと結果はサイト側で保存しています。
| 検証 | 結果 |
|---|---|
| 1. pythonの標準zipfileで日本語ファイル名を書き込む | flag_bits = 0x0800(ビット11 = True)。自動的にUTF-8化される |
| 2. 「日本語ファイル名.txt」のバイト数比較 | CP932で20バイト、UTF-8で28バイト。バイト列は完全に別物 |
| 3. ファイル名=CP932・ビット11=0でZIPヘッダを手組み(Windows標準ZIP機能を模した状況) | APPNOTE.TXT準拠の読み取りで実際に文字化けした |
| 4. ビット11=1のままファイル名バイト列だけCP932にする(不整合な組み合わせ) | UnicodeDecodeErrorが発生。文字化けで済まず読み取り自体が失敗した |
検証3では、「日本語ファイル名.txt」をCP932でエンコードしたバイト列を、ビット11を立てないままZIPヘッダに手作業で格納し、それをAPPNOTE.TXTの規定どおりCP437として解釈するリーダーで読み戻しました。結果は元の文字列とは一致しない記号の羅列になり、まさに「文字化け」と呼ばれる状態が再現されました。検証4は、ビット11を立てているのに中身がCP932のバイト列のままという、規格上ありえない組み合わせを試したものです。この場合はUTF-8として厳格にデコードしようとして失敗するため、文字化けよりもさらに手前の「読み取りエラー」で止まります。この2つの検証は、ビット11というたった1個のフラグと、実際のバイト列のエンコーディングが一致しているかどうかが、文字化けの有無を分ける核心であることを裏付けています。
他のアーカイブ形式・MIMEとの対比
ZIPのように「ビットの有無で解釈が変わる」仕組みは、すべてのファイル形式に共通するわけではありません。
| 形式 | ファイル名の格納方式 | ZIPとの違い |
|---|---|---|
| 7-Zip (.7z) | 常にヌル終端のwchar_t配列(kNamesセクション) | 「既定/UTF-8」という切替の概念自体が存在しない |
| RAR (RAR 5.0) | 常にUTF-8で格納 | ビットフラグによる切替がなく、常に単一のエンコーディング |
| MIME / Content-Disposition | filenameはISO-8859-1相当、filename*はRFC 5987方式 | 2つの異なるパラメータ名で文字集合が分かれる |
7-Zipの開発者公式リポジトリが公開する仕様書7zFormat.txtには、次のように記載されています。
wchar_t Names[NameSize];
7-Zipには、ZIPのような「既定エンコーディングかUTF-8か」という二層の切替概念がそもそもありません。ファイル名は常にwchar_tの配列として格納されます。ただし、7-Zip自体の文字化けが起こる条件については、当サイトでは調査していません。
RARLAB公式のRAR 5.0技術文書には、ファイル名について次の記載があります。
in UTF-8 format without trailing zero
RAR 5.0もビットフラグによる切替を持たず、常にUTF-8で格納する方式を採用しています。こちらも、文字化けが起こる具体的な条件そのものは今回確認していません。
HTTPのContent-Dispositionヘッダーで使われるfilenameパラメータは、RFC 6266 §4.3の記述によれば、filename*との対比の中でISO-8859-1相当の文字集合に限られることが示されています。
characters not present in the ISO-8859-1
それ以外の文字を扱うためのfilename*パラメータは、次のようにRFC 5987のエンコーディング方式を使います。
uses the encoding defined in [RFC5987]
このfilename*の構文は、charset'language'valueという3分割の形式とパーセントエンコーディングを基盤としており、その構文自体はRFC 2231に遡ります。ただしRFC 2231自体は「filename」という語やContent-Dispositionへの直接の言及を持たない一次資料である点には注意が必要です。filename*を解釈できない古い実装は、ISO-8859-1相当のfilenameパラメータにフォールバックするため、原文には次のようにあります。
do not understand the
フォールバックが起きると、ISO-8859-1に無い文字(日本語を含む多くの非ラテン文字)を含むファイル名は、文字化けしたり失われたりしうるという帰結になります。「文字化けする」という直接的な表現がRFC自体にあるわけではなく、フォールバック時の非互換性から生じる結果として整理したものです。
よくある質問
なぜWindowsで作ったZIPがMac・Linuxで文字化けするのですか?
APPNOTE.TXTの規定上、汎用フラグのビット11が立っていないZIPのファイル名は、規格上CP437として解釈される約束になっています。ビット11を立てずにCP932などの日本語コードページでファイル名を格納したZIPを、UTF-8/CP437前提で読むツールに渡すと、この記事で再現した文字化けの因果関係が働きます。ただし特定OSの現行実装の挙動そのものを断定するものではありません。
7-ZipやRAR形式を使えば文字化けしませんか?
7-Zipはファイル名を常にwchar_t配列として格納し、RAR 5.0は常にUTF-8で格納するため、ZIPのようなビットフラグの有無による切替は発生しません。ただし、7-Zip・RARそれぞれで文字化けが起こる条件そのものは今回調査しておらず、「文字化けしない」と断定するものではありません。
文字化けを避けるにはどうすればよいですか?
当サイトは特定のツール・手順を推奨する立場は取りませんが、規格上の事実として、汎用フラグのビット11を立ててUTF-8で格納する実装同士であれば、この記事で解説した不一致は生じにくくなります。実際の対処は利用しているツールの仕様をご確認ください。
MIMEのfilenameとfilename*は何が違いますか?
filenameパラメータはISO-8859-1相当の文字集合に限られますが、filename*パラメータはRFC 5987のエンコーディング(構文の基盤はRFC 2231)を使い、ISO-8859-1にない文字も表現できます。filename*を解釈できない実装はfilenameにフォールバックするため、非ISO-8859-1文字を含む名前は文字化け・欠落しうるとRFC 6266に記載されています。
出典・関連リンク
このページを引用する場合
本記事の情報を引用・紹介いただく場合は、記事名「ZIPで日本語ファイル名が文字化けする理由」と情報確認日「2026年7月26日」をあわせてお示しください。当ページへのリンクは任意です(リンクいただける場合は https://www.conbu.jp/tool/filename-limits/article-zip-mojibake.html をご利用ください)。
免責事項: 本記事はPKWARE・7-Zip・RARLAB・IETFの公式サイトではなく、特定のツール・実装における文字化けの有無を判定するものでもありません。掲載している内容は調査時点(2026年7月26日)で確認できた公式資料の要約と、この環境での実機検証の結果です。仕様は改定されうるため、利用前に必ず出典元の原典をご確認ください。詳細は免責事項をご確認ください。