7-Zipでファイル名がUTF-8で記録されたZIPファイルを作成する

# 先日の出来事

母「2年分の議事録を見やすい感じでメールに添付して！」
ぼく「普通にZIP形式でいいか…『送る』から『圧縮(zip形式)フォルダー』…待てよ、宛先のメールアドレスのドメインが `icloud.com` だ、Macを使っている可能性が高めに感じる。適当に作ったファイルだと文字化けするかもしれない。中身をチェックするか…あーUTF-8フラグ立ってないな…しかもこの感じだとUTF-8じゃないな…7-Zipで圧縮すればいい感じにしてくれるかな…あーダメだ、同じ感じだ…あーもういいや、時間無いしこのままでいいや！(『送る』で作成したZIPファイルを添付)」

その後、今のところ怒られ・文句・クレームなどは受けとっていない。
相手がMacを使っていたか、そして文字化けしたかどうかはわからない。

# 環境

* Windows 11 Home 22H2
* 7-Zip 23.01 (x64)

# ×：Windows標準の「送る」を使う

「送る」→「圧縮(zip形式)フォルダー」で圧縮する。

![「圧縮(zip形式)フォルダー」で圧縮](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/f253274f-379d-1a92-09a3-3ac437f740df.png)

すると、ファイル名はShift_JISで記録された。(画像赤枠)

![「圧縮(zip形式)フォルダー」で圧縮した結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/63631d87-922f-c16b-99ba-d74dae016a6a.png)

これを[CyberChef](https://gchq.github.io/CyberChef/)で展開すると、ファイル名は文字化けしてしまった。

![「圧縮(zip形式)フォルダー」で圧縮してCyberChefで展開した結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/326a5e0d-d105-1f83-fe43-d3f603083c80.png)

また、[さくらのクラウドシェル](https://www.sakura.ad.jp/services/cloudshell/)の `unzip` コマンドによる展開でも、ファイル名は文字化けしてしまった。

![「圧縮(zip形式)フォルダー」で圧縮してさくらのクラウドシェルで展開した結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/bdca7133-62f4-0425-6afb-af69763fb1a2.png)

# △：7-Zipで普通に圧縮する

7-Zipのコンテキストメニュー「"○○.zip"に圧縮」で圧縮する。

![7-Zipで普通に圧縮](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/707ecdad-f505-d312-53f5-460e95f9ed62.png)

メインのファイル名はShift_JISで記録された (画像赤枠) が、UTF-8のファイル名も Info-ZIP Unicode Path Extra Field として記録された。(画像青枠)

![7-Zipで普通に圧縮した結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/c28e3de3-3188-0ac3-592f-34a1f71cb1c8.png)

これを[CyberChef](https://gchq.github.io/CyberChef/)で展開すると、ファイル名は文字化けしてしまった。

![7-Zipで普通に圧縮してCyberChefで展開した結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/77ccf442-ea1f-55be-9e89-b32bc0376c01.png)

しかし、[さくらのクラウドシェル](https://www.sakura.ad.jp/services/cloudshell/)の `unzip` コマンドによる展開では、ファイル名の文字化けを回避できた。

![7-Zipで普通に圧縮してさくらのクラウドシェルで展開した結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/82fc34cd-6191-7b51-31fd-7e30f5b1cae2.png)

# ○：7-Zipでパラメーターをつけて圧縮する

[WindowsとMacのZIPファイルの文字化け問題とその解決策 | Gift by Gifted](https://gift-by-gifted.com/zip-garbled-characters/)
で紹介されていた方法である。

7-Zipのコンテキストメニュー「圧縮…」を選択する。

![7-Zipで圧縮](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/5002125e-a7a2-8292-323d-86841b65587b.png)

さらに、以下の設定を行って圧縮する。

* アーカイブ形式を「zip」にする
* パラメーターを `cu=on` にする

![7-Zipで圧縮 2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/135eef07-53ec-aa05-aabc-79e8241dd204.png)

すると、メインのファイル名がUTF-8で記録された。(画像赤枠)
さらに、general purpose bit flag のUTF-8フラグ (Language encoding flag) も立っていることが確認できる。(画像青枠)

![7-Zipで圧縮した結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/260db079-09fe-2d9f-b2cd-cbb7438f9a1f.png)

しかし、これを[CyberChef](https://gchq.github.io/CyberChef/)で展開すると、やはりファイル名は文字化けしてしまった。

![7-Zipで圧縮してCyberChefで展開した結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/c43fbe58-d68c-c030-c238-5ae6c47ccbbd.png)

[さくらのクラウドシェル](https://www.sakura.ad.jp/services/cloudshell/)の `unzip` コマンドで展開すると、文字化けはしなかったが、変なメッセージが出てしまった。
(local file header でも central directory header でも同様の general purpose bit flag とファイル名のデータが記録されているため、一方だけファイル名が `уБнуБУ.txt` だというメッセージの主張は変である)

![7-Zipで圧縮してさくらのクラウドシェルで展開した結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/0ed39a71-e2c8-4220-29d6-a826d9a1a71c.png)

# まとめ

7-Zipのパラメーター `cu=on` を用いることで、ファイル名がUTF-8のみで記録され、UTF-8フラグも立ったZIPファイルを作成することができた。
「ファイル名がUTF-8で記録されたZIPファイルを作成する」という目的では、これがやりたかったことである。

しかし、「互換性が高く、自然に展開できるZIPファイルを作成する」という目的では、このやり方が最善とは限らない。
今回の検証では、このやり方でメインのファイル名をUTF-8で記録したZIPファイルを作成しても、CyberChefでの文字化けは解消できなかったし、さくらのクラウドシェルでは変なメッセージが出てしまった。
さらに、(確かめてはいないが)古いWindows環境では、逆にUTF-8に対応しておらず、文字化けしてしまうかもしれない。
そう考えると、パラメーターを使わずに7-Zipで普通に圧縮して生成した、メインのファイル名はShift_JISで記録し、別にUTF-8のファイル名も格納する形式の方が、多くの環境で受け入れられやすいかもしれない。
とはいえ、メインのファイル名をUTF-8で記録する形式には対応しているが、この形式には対応していない環境もあるかもしれない。

本当に多くの環境で使ってもらいたければ、そもそもファイル名に文字化けを気にするような文字を使わず、ASCIIで表現できる文字のみを使ったものを圧縮するのがいいだろう。

それにしても、ファイル名をShift_JISのみで記録する「送る」は、ファイルサイズの観点からは良いかもしれないが、互換性の観点からは最悪であるといえよう。
7-Zipでも圧縮を行ったにも関わらず、結果をよく確認せずにメインのファイル名のみを見て「UTF-8で記録されていない」と思い込み、「送る」で作成したZIPファイルを採用してしまった自分は愚かだったなあ。