【问题标题】:Correctly decoding zip entry file names -- CP437, UTF-8 or?正确解码 zip 条目文件名——CP437、UTF-8 还是?
【发布时间】:2012-11-07 00:01:46
【问题描述】:

我最近编写了一个名为 zipzap 的 zip 文件 I/O 库,但我正在努力从任意 zip 文件中正确解码 zip 条目文件名。

现在,PKWARE spec 声明:

D.1 ZIP 格式历来仅支持原始 IBM PC 字符 编码集,通常称为IBM Code Page 437...

D.2 如果未设置通用位 11,则文件名和注释应符合 转换为原始 ZIP 字符编码。如果设置通用位 11,则 文件名和注释必须支持 Unicode 标准,版本 4.1.0 或 使用 UTF-8 存储定义的字符编码形式更好 规范...

这意味着符合标准的 zip 文件将文件名编码为 CP437,除非设置了 EFS 位,在这种情况下文件名是 UTF-8。

不幸的是,似乎很多 zip 工具要么没有正确设置 EFS 位(例如 Mac CLI、GUI zip),要么使用其他编码,通常是默认系统编码(例如 WinZip?)。如果您知道 WinZip、7-Zip、Info-Zip、PKZIP、Java JAR/Zip、.NET zip、dotnetzip 等如何对文件名进行编码,以及当压缩,请告诉我。

特别是,Info-Zip 在解压缩时会尝试这样做:

  • 文件系统 = MS-DOS (0) => CP437
    • 除了:版本 = 2.5、2.6、4.0 => ISO 8859-1
  • 文件系统 = HPFS (6) => CP437
  • 文件系统 = NTFS (10) 和版本 = 5.0 => CP437
  • 否则,ISO 8859-1

如果我想支持检查或从任意 zip 文件中提取并在没有 EFS 标志的情况下对文件名编码进行合理尝试,我可以寻找什么?

【问题讨论】:

    标签: jar zip 7zip zipfile winzip


    【解决方案1】:

    目前情况如下:

    • 大多数 Windows 实现都使用 DOS (OEM) 编码
    • Mac OS zip 实用程序使用 utf-8,但它不设置 utf-8 位标志
    • *nix zip 实用程序静默使用系统编码

    所以唯一的方法是检查文件名是否包含类似 utf-8 字符的内容(检查 utf8 编码的描述 - 第一个字节应该是 110xxxxx,第二个 - 10xxxxxx 用于 2 字节编码的字符)。如果是正确的 utf8 字符串 - 使用 utf8 编码。如果不是 - 回退到 OEM/DOS 编码。

    【讨论】:

      【解决方案2】:

      在不使用 EFS 标志的情况下确定文件名是否编码为 UTF-8 的唯一方法是检查是否在其中一个字符中设置了高位。这可能可能意味着该字符是 UTF-8 编码的。但是,它仍然可能是另一种方式,因为 CP437 中的某些字符设置了高位并且不打算解码为 UTF-8。

      我会坚持 PKWARE 应用笔记规范,而不是尝试遵循现有的每个已知 zip 应用程序的解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-22
        • 2019-05-23
        相关资源
        最近更新 更多