[4]
多くのファイル・システムやその実装では、その環境で使える文字の全てかファイル名に使えるわけではない。例えば、 FAT や NTFS ではディレクトリ (フォルダ) 区切子として使われる \
を名前に使うことが出来ない。
[5] ファイル名における大文字と小文字の取り扱いは、 プラットフォームとファイルシステムに依存する複雑な問題です。
[6] 大文字と小文字の違いは、単にそのプラットフォーム内部だけの問題に留まりません。 例えば大文字と小文字を区別しないプラットフォームで作られた HTML文書中の相対URL に大文字と小文字の違いを気にしないでファイル名を書くと、 区別されるプラットフォームに移動したときにリンクが機能しなくなります。
[7] 比較 (ファイルの参照やファイル名の衝突の判定) において大文字と小文字を区別するかという問題と、 ファイル名が大文字と小文字を正規化した状態で保存されるかという問題があります。
[8] その他に比較的軽微な問題として、 大文字と小文字のみ異なる改名が可能かどうか、 整列でどう扱われるかなどの問題もあります。
[9] 当該ファイルシステムでどのような文字コードを使うかにより、 大文字と小文字の変換や同一視が行われる文字集合の範囲も変わってきます。 ロケール等で異なる大文字と小文字の扱いや、 Unicodeの版による違いをファイルシステムやプラットフォームの API でどう扱うかも問題になってきます。
[10] ファイルシステムをまたがる移動、 書庫ファイルやネットワークによる転送などで、 取り扱いの違いが問題となることがあります。
[12] ファイルシステムによっては長いファイル名と短いファイル名のような異なるファイル名を1つのファイルに与えることが出来る場合がありますが、 ファイル名ごとに適用される規則が違うことがあります。
[21] ISO 9660 では大文字と小文字を区別しません。
[23] OpenVMS の ODS-2, NetWare の NSS, NWFS も区別しないとのこと。
[22] APFS は大文字と小文字を区別しないモード (既定値) と区別するモードがあります。
[24] OpenVMS の ODS-5 も両モードあって区別しないのが既定値とのこと。
[25] HFS+ の既定値は不区別、 case-preserving で、区別するモードもある。
[31] NTFS は不区別、 case-preserving で、フォルダー単位で区別させることもできる。 >>30
[33] ext4 は区別しますが、ディレクトリー単位で区別させないこともできます。 >>32
[19] ファイルシステムと大文字小文字 #case-sensitive - Qiita, https://qiita.com/jokester/items/f8a106832af2d3eb3436
[42] Using the Linux kernel's Case-insensitive feature in Ext4, https://www.collabora.com/news-and-blog/blog/2020/08/27/using-the-linux-kernel-case-insensitive-feature-in-ext4/
[29] FAT など古くからあるファイルシステムではASCII大文字・小文字不区別。
[27]
NTFS は初期化時に作られる $UpCase
ファイルで大文字と小文字の関係を決めている。
初期化に使ったプラットフォームが持っている対応表が反映される。
>>28, >>26
[44] トルコ文字と case insensitive filesystem - 彷徨えるフジワラ, https://flying-foozy.hatenablog.com/entry/20120102/1325473117
[43] Internationalization for the NFSv4 Protocols, David Noveck, , https://www.ietf.org/archive/id/draft-ietf-nfsv4-internationalization-07.html#section-6.3
[38] Unicode正規化は破壊的処理なので要注意です。
[39] HFS+ はデータ破壊を避けるために独自の手法を使っています。
[40] >>34 >>35 は NFC と full case folding を採用しています。
[41] >>40 本当に実装されているのかは謎。まあこれはファイルの要件なので、 意図的にそういうファイルを作ろうとしなければ自然に満たせる、か?
[45] case の insensitive と preserve - 彷徨えるフジワラ, https://flying-foozy.hatenablog.com/entry/20120104/1325657430
[2] filename=""
も参照。
[160] ZIPファイルでは歴史的に様々な文字コードが使われてきました。 他の分野と比較しても UTF-8 の普及が遅く、現在も UTF-8 と旧来の文字コードが混在して使われ続けています。
です。
Content-Type
charset
に相当するもの)
がありません。「ZIPファイルの処理」の範疇では、
ZIPファイルに含まれるファイルの内容はバイト列として扱われるだけであり、
その文字コードが問題となることはありません。[167] ZIP には「ZIPファイル全体の文字コード」のような概念はありません。
[168] 格納される各ファイルにファイル名があり、それは何らかの文字コードで記述されています。
[169] 注釈や合言葉も文字コードが関係してきますが、 あまり問題とされることは少ないようで、ファイル名が ZIPファイルにおける文字コードの主要な問題領域となっています。
[170] ZIP は元々米国で DOS 向けの製品として開発されました。そのため、 現在の ZIP 仕様書にも
D.1 The ZIP format has historically supported only the original IBM PC character
encoding set, commonly referred to as IBM Code Page 437. This limits storing file name characters to only those within the original MS-DOS range of values and does not properly support file names in other character encodings, or languages.
と説明されています >>159。 つまり CP437 が ZIP の本来の文字コードであるとされます。 CP437 は米国市場等の MS-DOS で使われていたコードページです。
[53] 程なくして ZIP は米国以外の諸国の DOS でも使われるようになりました。 米国版もその他の版も、おそらく文字コードの変換は一切なく、 プラットフォームのファイル名をそのまま格納したり、 逆にそのままZIPファイルから展開したりしていたと推測されます。 そのため各国で自国の MS-DOS の採用するOEMコードページをファイル名とする ZIPファイルが流通することになりました。
[171] Windows の時代になると、 Windows が採用する ANSIコードページがファイル名に使われるようにもなりました。 しかし MS-DOS との互換性のため、 OEMコードページも使われ続けました。
[172] 更に時代が進むと、 UTF-8 がファイル名に使われるようにもなりました。
[55] 時代の変化を踏まえて ZIP の公式仕様にも変更がありました。 general purpose bit 11 を使って UTF-8 を使うことが明示できるようになりました。
[173] ZIPファイルには、格納するファイルごとにファイル名その他の情報を記述できます。
[174] general purpose bit 11 (0x0800) は、ファイル名等が UTF-8 で符号化されているかどうかを表します。
[175] 11 が設定されていないときは、ファイル名と注釈は、 original ZIP character encoding (>>170) に適合するべきです。 >>159
[176] 11 が設定されているときは、ファイル名と注釈は、 UTF-8 storage specification によって定義された文字符号化形を使い The Unicode Standard 4.1.0 以上に対応しなければなりません。 >>159
[182] このビットのことを便宜上 UTF-8フラグと呼ぶことがあります。
[177] ZIPファイル内の UTF-8 で符号化されたデータは、 BOM を含まないことが期待されます。 >>159
[190] general purpose bit 11 は、 ファイルの内容や合言葉の符号化を暗示するものではありません。 >>159
[180] エラー処理などは規定がなく不正な UTF-8 をどう扱うべきか不明です。
[58] 現在では UTF-8フラグを利用して出力する実装が多くなってきており、 ZIP を使うファイル形式等でこれの利用を要求する技術仕様もあります。
[183] しかし現在でもすべての実装が UTF-8 で出力するわけではなく、 UTF-8 で出力する実装のすべてが UTF-8フラグを設定するわけでもありません。 UTF-8 の出力に対応していても、 UTF-8 や UTF-8フラグを既定で設定しない実装もあるようです。
[184] 現在では多くの実装が UTF-8 の復号や UTF-8フラグの理解に対応しているようです。 しかしすべての実装が正しく取り扱えるかどうかは不安があります。
[157] XユーザーのBinary numberさん: 「えー zip圧縮についてなんですがぁ... 調査の結果 Macが圧縮時にエンコードをUTF-8にしてるにもかかわらず、General purpose bit 11にフラグを立てずに圧縮するのが悪いってことがわかりました()」 / X, , https://x.com/_actbit/status/1867033742738591908
[158] 現代的ではなく相互運用性のため好ましくないのはその通りだが、歴史的経緯も何もかも無視してこのように Mac vs Windows の対立構造に持ち込んで貶めるために使うのは倫理的でない。
[192] Info-Zip Unicode 欄は、 general purpose bit 11 が好ましからざるときに使えます。 具体的には古いプログラムとの後方互換性が求められるときが想定されているようです。 >>159
[193] Info-ZIP Unicode Comment Extra Field (0x6375) には UTF-8 版のファイル注釈を蓄積できます。 >>159
[194]
その UnicodeCom
欄の値が、 entry comment の UTF-8 版であります。
BOM
は使いません。
>>159
[196] Info-ZIP Unicode Path Extra Field (0x7075) には UTF-8 版のファイル名を蓄積できます、 >>159
[197]
その UnicodeName
欄の値が、 entry File Name の UTF-8 版であります。
BOM
は使いません。
>>159
[203] 明記はされていませんが、対応している実装は、 Info-ZIP Unicode 欄が存在する場合にそちらを採用し、 通常のファイル名と注釈を無視することが期待されているようです。
[200] general purpose bit 11 と Info-ZIP Unicode 欄の2つの方法がありますが、 使い分けについては次のような定めがあります。
[201] ZIPファイル生成時にどちらの方法によるかは、実装依存です。 >>159
[195] ファイル名と注釈の両方が UTF-8 のときは General Purpose Bit 11 (language encoding flag (EFS)) を設定することができるので、そちらを使うべきであり、 Info-ZIP Unicode Path extra field と Info-ZIP Unicode Comment extra field は使うべきではありません。 >>159
[198] ただ後方互換性のため、 general purpose bit 11 はZIPファイルに含めるファイルの path や comment の native character set が既に UTF-8 の場合に限って使うべきです。 >>159
[199] general purpose bit 11 によるか、 Info-ZIP Unicode extra field を使うかは、 Local Directory Header と Central Directory Header とで同じとすることが期待されます。 >>159
[202] 開発者は、ZIPファイルがどちらの方法も想定し、 どちらも読み取れるようにするべきです。 >>159
[204] 実際に各種の実装がどれくらいこれらを生成するのかは不明です。 実装例がないことはないようですが (それこそ Info-ZIP が実装しているのでそれなりの利用が想定されます)、 よく使われているということでもなさそうです。
[205] 実際にどれくらい読み取りに対応されているのかも未知数です。
[206] 現在となっては UTF-8フラグに対応していないのに Info-ZIP Unicode 欄には対応している実装は残っていないでしょうし、 UTF-8 ファイル名を含めたいのに UTF-8 に対応していない実装も考慮したいという状況もあまりないでしょうから、 Info-ZIP Unicode 欄はあまり使うべきではないと思われます。
[265] >>263 は Info-ZIP Unicode Path Extra Field (0x7075) の読み取りにも対応しているようです。
[185] 0x0008 Extra Field というものがあり、 Reserved for extended language encoding data (PFS) と説明されています。 >>159
[186] 応用は、 0x0008 Extra Field を使って file name storage を補足できるとされます。 しかしこれは optional field であり、その保存形式は現在未定義とされます。 >>159
[187] 0x0008 Extra Field は、 general purpose bit 11 が設定されている場合でも、 設定されていない場合でも使えます。 >>159
[191] ファイルの内容や合言葉の符号化は、 general purpose bit 11 が影響するものではなく、 0x0008 Extended Language Encoding Extra Field に蓄積しなければなりません。 >>159
[188] source or target encoding についての extended information を蓄積するものであって、 応用がファイル名やファイルの内容の符号化の task を更に補助するようなものが想定されます。 具体例として Java modified-UTF-8 であるか否か、 UTF-8-MAC であるか否かのような情報の格納に使えます。 また、文字符号化 (コードページ) の指示も指定できます。 これを使って CP437 や UTF-8 と違う符号化を ZIPファイル内で使えます。 >>159
[189] つまり「何かもっと詳しい情報を書ける」ということだけが決まっていて、 具体的なものは何もありません。 読み書きとも無視するのが妥当と考えられます。
[214] Xceed なる実装が Xceed Unicode extra field (0x554E) を使っています。 >>211, >>213
[215]
ファイル名と注釈を格納できます >>211, >>213。どちらも UTF-16LE で
BOM
なしです。
[216] >>213 に当該実装で生成した ZIPファイルの実例があります。
[210] 実際にどの程度使われているか不明です。 >>213 はメタ情報を表示するだけのソフトウェアですが、 それと本家 Xceed 以外に対応している実装も知られていません。
[208] ZipArchive なる実装が ZipArchive Library Extra Field (0x5A4C) を定めています。 >>207
[209] ファイル名のコードページ、 ファイル名、 注釈のコードページを記述できるとしています。 >>207
[210] 実際にどの程度使われているか不明です。 これらが利用されたファイルも見つけることができません。 このソフトウェア自体の配布ファイルでも使われていません。
[67] ファイルが追加された OS や ZIP 仕様の版の情報があります。 PKZip の場合、追加したOSと版番号が入るようで、 これを見て OEMコードページとANSIコードページを読み分ける実装があるようです (>>266 >>267)。
[88] ZIP を生成するソフトウェアが限られていて、 その挙動がすべてわかりきっている場合ならこの方法でもうまくいくのでしょうが、 実際に流通する ZIPファイルを見るにこの方法はあまり有効とは思えませんが、 どうなのでしょう。
[217] 文字コードの情報はファイルごとに格納されています。
[218] つまりファイルによって異なる文字コードが使われる可能性があります。
[219] 実際に UTF-8フラグ付きの UTF-8 のファイル名のファイルと、 UTF-8フラグなしの旧来の文字符号化のファイル名のファイルが同じ ZIPファイルに混在する事例がちらほらみられます。
[220] そうした事例の中には、ディレクトリーで非ASCII文字が使われていることもあります。 ZIP ではファイル名にディレクトリーも混在するので、 バイト列として見たときに異なるのに、 実際には文字列として等しいディレクトリーが含まれている場合があります。 バイト列を正しく復号できれば単一のディレクトリーになりますが、 誤って復号すると正しい名前と文字化けした名前の2つのディレクトリーに分裂することになります。
[221] 実際に流通しているかどうかは不明ですが、 UTF-8フラグなしで、異なる文字コードのファイル名のファイルが混在することも理論上はあり得ます。 異なるプラットフォームで既存の ZIPファイルに新しいファイルを追加すると、 特別な知識なしでも容易にそうしたファイルを作り得ます。 ただそうしたZIPファイルはほぼ確実に文字化けして表示されることになりますし、 そうした作り方で異なるプラットフォームを移動しながらファイルを追加していくという状況はあまりなさそうですから、 そのようなZIPファイルが流通し続けることは稀かもしれません。
[222] こうした文字コードの混在と同名だったり同名でなかったりするファイル名の取り扱いは、 セキュリティー上の問題を引き起こすこともありますし、 そうでなくても不具合の温床となりますから、実装者は注意が必要です。
[13] ZIPファイルのファイル名では UTF-8 が使われる場合が多くなっているものの、 UTF-8 以外の ZIPファイルも過去に作成され大量に蓄積されていますし、 現在でも依然として生産され続けている実情があります。
の読み込みに対応する必要があります。
[224] UTF-8フラグがない場合、どの文字コードが使われているかは ZIPファイル内に明記されないため、何らかの手段で決定しなければなりません。
[56]
一般にバイト列の文字コードの決定方法は何通りかありますが
[238] 使われ方がある程度決まったソフトウェアなら利用環境などの事前知識を使うことができますが、 どんな入力があるかわからない汎用のソフトウェアは推定手法を組み合わせることになります。
[239] バイト列や URL を使った推定手法は HTML などで用いられており、 参考にできます。ただし、
といった ZIP 固有の事情があるので、 Web 用そのままでは必ずしも有効な実装になりません。
[225] 文字コードの決定は、厳密にはファイルごとに行うべきですが、 ファイル名は短いことが多く文字コードの判定が難しい場合があること、 ファイルごとにファイル名の文字コードが異なる場合は無視していいと思われること (>>221) から、 単独ではなく組み合わせにより行うことで精度を高められると考えられます。
[243] UTF-8 との混在 (>>220) がある場合、 UTF-8 でない文字コードの復号の結果と文字の分布が近い (ディレクトリーが該当する場合は部分一致する) 可能性があり、このことを推定の材料にできるかもしれません。
[244] UTF-8フラグがないファイル名で使われる文字コードの全体像は不明です。 これまでに大規模な調査などは行われたことが無さそうですし、 実行環境等に依存しない汎用的な実装をどのように作るべきかという議論もほとんど見られませんから、 手がかりが多くありません。
[245] 実例 (>>69) がある文字コードの他に、 実装例が知られている文字コードがいくつかあり、 それ以外に言及がある文字コードもいくつかあります。 こうした情報をヒントにできそうです。 ただしZIPファイルは公開 Web でやり取りされないものも大量に存在すると考えられますから、 Web 上で実例が見つけられるものだけに限定して考察するのは危険と思われます。
[246] OEMコードページはすべて使われる(た)と想定するのが良いかもしれませんが、 歴史的にあまり使われなかったらしいOEMコードページもあるので、 それらは ZIP でも使われなかった可能性があります。
[247] ANSIコードページはすべて使われる(た)と想定するのが良いかもしれませんが、 OEMコードページがもっぱら使われANSIコードページは使われなかったものもあるかもしれません。
[250] 従って、一応主要なコードページはすべて ZIPファイルで出現し得るものとして対応するべきと考えられます。 具体的な一覧と、主に使われた国や言語との対応関係については、 コードページの項にある一覧表を参照。
[266] >>263 によると PKZip for Windows 2.5, 2.6, 4.0 は central directory header で OEMコードページを使い、 local directory header でANSIコードページを使うようです。 それに対処するための分岐とテストコードがあります。
[267] >>263 によると PKZip version 5 以上は OEMコードページを使うようです。 それに対処するための分岐とテストコードがあります。
[268] PKZip という公式実装が使っている OS と ZIP の版の情報を OEMコードページとANSIコードページのどちらかの判定に使っているわけです。 ただ公式実装以外がこれらをどう使っているかは怪しいところではありますし、 実際の Web 上のファイルを見るにこの判定条件で正確に対処できるのかは疑わしいように思われます。 ある程度のヒントには使えるのかもしれません。
[248] DOS や Windows で主に使われた文字コードの他に、 Unix で主に使われた文字コードや Mac の文字コードが言及されることもあります。 ただ、歴史的に ZIPファイルは主に DOS 系の環境で使われてきたもので、 それ以外の環境では主に DOS 系の環境との互換性を意識して ZIPファイルを使うことが多かったと推測されますから、 Unix や Mac の文字コードを使った ZIPファイルの流通量はそれほど多くない(なかった)と思われます。
Convert filenames inside ZIP archives from autodetected older Russian encodings (koi8-r, koi8-u, cp866, windows-1251) to UTF-8.
と説明しており、キリル文字を使う KOI8-R, KOI8-U, CP866, Windows-1251, UTF-8 についてキリル文字の出現頻度の情報から自動判定します。
[252] >>78 ではシフトJIS、日本語EUC、ISO-2022-JP、UTF-8 から自動判別する実装が紹介されています。また、 シフトJISや日本語EUCのテストファイルも掲載しています。 しかし ISO-2022-JP は生成する実装があるのか不明としています。
[89] 【2025年】zip圧縮・展開(解凍) おすすめソフト12選まとめ+解説、文字化けよさらば!【Win・Mac】 #Windows - Qiita, https://qiita.com/ko1nksm/items/b1e320f418614372c43e
zip ファイルに関しても、macOS は Shift JIS に対応しています。ただし Windows 拡張版の CP932 ではなく、Mac OS 拡張版の MacJapaneseです。つまり古い Mac OS で作成した zip ファイルを展開できるようになっています。zip ファイルの中のファイル名の文字コードは国によって様々な文字コードが使われてきました。様々な文字コードが使われる状況では文字化けしやすいのは当然です。現在では Windows も macOS も Unicode を使っているわけで、あなたに Shift JIS を使う理由がないのであれば、zip ファイルの中のファイル名にも Unicode (UTF-8) を使いましょう。
[141] なお、 >>89 は ZIP のプロファイルの1つである ISO/IEC 21320-1:2015 を 「ISO/IEC の zip の標準規格」 という誇大な説明によって自説の補強に用いています。 まあ ZIP のプロファイルは一種の ZIP の標準と言えなくもないのですが、 ZIP の主要な技術仕様は他の文書を参照しているだけで、 直接的にはそれに対する追加の制約部分のみしか含まれないのですから、 誤解を招くだけであり、健全な説明とはいえません。 当該主張それ自体には問題がないのに、 無理な論拠を提示することによって優良性の誤認を誘発し、自ら有用性を毀損している残念な例です。
Windows 標準の zip 機能は、正しい UTF-8 ファイル名(UTF-8 フラグが設定、または Unicode パス拡張フィールドの設定)であれば問題なく展開できたのですが、macOS 標準機能で作成した zip ファイルは、正しい UTF-8 ファイル名ではないので文字化けしてしまいます。他のソフトで文字化けしないのは、おそらく別の情報を参照しており、zip ファイルの情報に作成 OS が「Unix」と記録されていれば UTF-8 だろうと推測しているようです。
[269] ZIPファイルのファイル名の文字コードの判定は、 一般の文字コードの判定問題に加えて ZIPファイル特有の事情にも配慮が必要です (>>239)。
[270]
一般の文字コードの判定問題も完全に正確に回答を得ることは不可能で、
各種実装をみてもどれも一長一短で完璧なものはありません。
[271] 従ってURLやロケールなどの補助的情報があれば、それを組み合わせて候補を絞り込むことが重要になってきます。
[272] 誤判定を予期して、実行時オプション等の形で手動で上書きする仕組みを併用することも重要です。
[76] 実装事例等:
[69] 各種文字コードのファイル名の入ったZIPファイル:
[68]
同じ UTF-8 でも Windows などでは NFC 系の正規化に近い状態が一般的で
(ただし必ずしも正規化されるわけではない)、
Mac では NFD 系の正規化が適用されている状態
(
[273] ZIPファイルの文字コードを扱う実装や解説などの中には、 Mac の挙動を UTF-8-MAC などと称するものがあります (ZIPファイルに限らず、 この話題でしばしば使われる通称です)。
[275] 中には Mac の挙動が不適切であるかのように扱うものもあります >>140 が、 Mac がおかしなことをしているわけではありません。 現実に不都合が生じるかもしれませんが、それは Mac が悪いのではなく、 Unicode と ZIP の仕様に由来する不便です。
[276] ZIPファイルから取り出したファイルのプラットフォームのファイルシステム上のファイル名をどのように決めるかは、 ZIPファイル内のファイル名とファイルシステムの制約を勘案しつつ決めなければなりません。 ファイルシステムの必須の制約を満たすことは不可避の条件となりますが、 必須条件でないプラットフォームの慣習とZIPファイルの格納値の折り合いをどうつけるかは、 設計方針の問題となります。