YorozuyaIT
Japanese Text & Encoding

Garbled Japanese Filenames After Unzipping: Why It Happens and How to Fix It

Written by the Yorozuya IT editorial team, based in Japan. Menus, apps, and rules change, so check the date.

Short answer

You receive a ZIP from a colleague in Japan. You extract it and get ô·û{îΩ.txt instead of 日本語.txt. The data is fine; the names are being read with the wrong encoding.

Why ZIP gets this wrong

The ZIP format began in the 1980s with filenames in the old DOS character set (CP437). Later, the format added one flag, bit 11 of the general-purpose flags, to say "this name is UTF-8". Tools that set the flag are read correctly everywhere. Tools that do not set it leave readers to guess.

Flow chart: ZIP readers check the UTF-8 flag, otherwise guess CP437 or the local code page

Many Windows tools, especially on Japanese-locale systems, store names in CP932 without the flag. Extract that on a Mac or a Linux server using the default guess and you get mojibake. The reverse also happens: archives created on macOS use UTF-8 names (often in decomposed form), and older Windows tools can misread them.

Fix on Linux: tell unzip the encoding

On Debian and Ubuntu, the unzip package supports an encoding option:

unzip -O CP932 from_japan.zip -d out/

The Mac's bundled unzip may not offer -O. A GUI tool such as The Unarchiver, which detects encodings, is the easy route there.

Fix in Python: re-decode the names

Python's zipfile decodes names as CP437 when the UTF-8 flag is missing. Because CP437 maps all 256 byte values to characters, you can reverse that step and decode the original bytes as CP932:

import os
import zipfile

def real_name(info, legacy="cp932"):
    name = info.filename
    if not info.flag_bits & 0x800:        # UTF-8 flag not set
        name = name.encode("cp437").decode(legacy)
    return name

base = os.path.abspath("out")
with zipfile.ZipFile("from_japan.zip") as z:
    for info in z.infolist():
        dest = os.path.abspath(os.path.join(base, real_name(info)))
        if not dest.startswith(base + os.sep):
            continue                       # skip suspicious paths
        if info.is_dir():
            os.makedirs(dest, exist_ok=True)
            continue
        os.makedirs(os.path.dirname(dest), exist_ok=True)
        with z.open(info) as src, open(dest, "wb") as dst:
            dst.write(src.read())

Run it on a small archive first and check the extracted names. If they still look wrong, try "shift_jis" or another legacy encoding.

Make ZIPs that travel

If you create the archive for people on other systems:

The voiced-mark problem

Files from macOS often have names in NFD, where が is か plus a combining mark. In some tools it looks identical but will not match a search for the normal form, and editing the name may delete only the mark. After extraction, convert names to NFC. The NFC vs NFD guide shows how.

Quick checklist

FAQ

Is the file content damaged?

No. Only the names are misread. The data inside the archive is intact.

Why do some Mac-created ZIPs show broken voiced marks on Windows?

macOS commonly produces decomposed (NFD) Unicode names, where が is stored as か plus a separate mark. Some Windows tools display or compare these oddly. Normalize the names to NFC after extracting.

Can I just rename the files by hand?

For two files, yes. For dozens, re-decode the names programmatically so you do not have to guess the originals.

Keep reading