正确解码zip条目文件名 - CP437,UTF-8或?

时间:2012-11-07 00:01:47

标签: jar zip 7zip zipfile winzip

我最近编写了一个名为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等如何编码文件名以及他们将“版本由”字段设置为何时 zipping < / em>,请告诉我。

特别是,当解压缩

时,I​​nfo-Zip会尝试此操作
  • 文件系统= MS-DOS(0)=&gt; CP437
    • 除外:版本= 2.5,2.6,4.0 =&gt; ISO 8859-1
  • 文件系统= HPFS(6)=&gt; CP437
  • 文件系统= NTFS(10)和版本= 5.0 =&gt; CP437
  • 否则,ISO 8859-1

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

2 个答案:

答案 0 :(得分:2)

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

我会坚持使用PKWARE应用笔记规范而不是破解试图符合现有的每个已知zip应用程序的解决方案。

答案 1 :(得分:2)

目前的情况如下:

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

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