zip 文件编码 (C# / ionic-zip)
Encoding of files inside a zip (C# / ionic-zip)
我们遇到了 zip 文件中文件编码的问题。
我们正在使用 ionic zip 来压缩和解压缩档案。
我们位于丹麦,所以我们经常有文件名中包含 æ、ø 或 å 的文件。
当用户使用 windows 内置工具压缩文件时,我发现它使用的是 IBM437 编码,当我们的文件带有 'ø' / 'Ø 时,这只会给出一些奇怪的结果' 在他们中。我用以下代码解决了这个问题:
public static string IBM437Encode(this string text)
{
return text.Replace('ø', '¢').Replace('Ø', '¥');
}
public static string IBM437Decode(this string text)
{
return text.Replace('¢', 'ø').Replace('¥', 'Ø');
}
这 运行 已经有一段时间了,一切都很好。
但是,因为总有一个但是,我们没有用macosx中默认工具压缩的文件来尝试。
所以现在我们遇到了一个新问题..
当使用 æ、ø 和 å 时,编码为 UTF-8!
所以如果我知道 zip 被压缩的位置,我就可以让它工作,但是有什么简单的方法可以检测或规范化 zip 内的编码吗?
检测编码总是一件棘手的事情,但是 UTF8 has strict bitwise rules about what values are expected in a valid sequence, and you can initialize a UTF8Encoding object in a way that will fail by throwing an exception when these sequences are incorrect:
public static Boolean MatchesUtf8Encoding(Byte[] bytes)
{
UTF8Encoding enc = new UTF8Encoding(false, true);
try { enc.GetString(bytes) }
catch(ArgumentException) { return false; }
return true;
}
如果您 运行 在 zip 中的所有文件名中,您可以确定它是否在任何地方失败,在这种情况下,您可以得出结论,名称未保存为 UTF-8。
请注意,除了 UTF-8 之外,计算机的默认编码之间也存在令人讨厌的差异(Encoding.Default
,在美国和西欧国家通常为 Windows-1252,但因地区而异和语言)和您已经遇到的 DOS-437 编码。
区分它们非常非常困难,可能需要通过实际检查每个超出字节 0x80 的编码范围产生正常的重音字符,以及您通常不会想到的特殊字符来完成在文件名中遇到。例如,许多 DOS-437 字符是用于在 DOS 中绘制半图形用户界面的框架。
供参考,这些是 DOS-437 中的特殊字符(因此字节范围为 0x80-0xFF):
80 ÇüéâäàåçêëèïîìÄÅ
90 ÉæÆôöòûùÿÖÜ¢£¥₧ƒ
A0 áíóúñѪº¿⌐¬½¼¡«»
B0 ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐
C0 └┴┬├─┼╞╟╚╔╩╦╠═╬╧
D0 ╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀
E0 αßΓπΣσµτΦΘΩδ∞φε∩
F0 ≡±≥≤⌠⌡÷≈°∙·√ⁿ²■
并且在 Windows-1252 中:
80 €�‚ƒ„…†‡ˆ‰Š‹Œ�Ž�
90 �‘’“”•–—˜™š›œ�žŸ
A0 ¡¢£¤¥¦§¨©ª«¬�®¯
B0 °±²³´µ¶·¸¹º»¼½¾¿
C0 ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ
D0 ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß
E0 àáâãäåæçèéêëìíîï
F0 ðñòóôõö÷øùúûüýþÿ
其中一些甚至无法打印,因此它更容易一些。
如您所见,一般来说,DOS-437 的大部分重音字符位于 0x80-0xA5 区域(0xE1 处的 Beta 在德国通常用作 eszett),而 Win-1252 实际上有它们都在区域 0xC0-0xFF 中。如果您确定了这些区域,您可以建立一个扫描机制来评估它似乎倾向于哪种编码,只需计算每个区域落在预期范围内和之外的数量。
请注意,c# 中的 Char
表示一个 unicode 字符,无论它是从什么字节加载的,并且 unicode 字符具有某些分类,您可以通过编程方式查找这些分类以区分普通字母(可能带有变音符号) ) 和各种 类 特殊字符(简单示例:我知道其中一个 类 是 "whitespace characters")。可能值得研究该系统以自动确定 "normal language characters" 是什么的过程。
我们遇到了 zip 文件中文件编码的问题。 我们正在使用 ionic zip 来压缩和解压缩档案。 我们位于丹麦,所以我们经常有文件名中包含 æ、ø 或 å 的文件。
当用户使用 windows 内置工具压缩文件时,我发现它使用的是 IBM437 编码,当我们的文件带有 'ø' / 'Ø 时,这只会给出一些奇怪的结果' 在他们中。我用以下代码解决了这个问题:
public static string IBM437Encode(this string text)
{
return text.Replace('ø', '¢').Replace('Ø', '¥');
}
public static string IBM437Decode(this string text)
{
return text.Replace('¢', 'ø').Replace('¥', 'Ø');
}
这 运行 已经有一段时间了,一切都很好。
但是,因为总有一个但是,我们没有用macosx中默认工具压缩的文件来尝试。 所以现在我们遇到了一个新问题.. 当使用 æ、ø 和 å 时,编码为 UTF-8! 所以如果我知道 zip 被压缩的位置,我就可以让它工作,但是有什么简单的方法可以检测或规范化 zip 内的编码吗?
检测编码总是一件棘手的事情,但是 UTF8 has strict bitwise rules about what values are expected in a valid sequence, and you can initialize a UTF8Encoding object in a way that will fail by throwing an exception when these sequences are incorrect:
public static Boolean MatchesUtf8Encoding(Byte[] bytes)
{
UTF8Encoding enc = new UTF8Encoding(false, true);
try { enc.GetString(bytes) }
catch(ArgumentException) { return false; }
return true;
}
如果您 运行 在 zip 中的所有文件名中,您可以确定它是否在任何地方失败,在这种情况下,您可以得出结论,名称未保存为 UTF-8。
请注意,除了 UTF-8 之外,计算机的默认编码之间也存在令人讨厌的差异(Encoding.Default
,在美国和西欧国家通常为 Windows-1252,但因地区而异和语言)和您已经遇到的 DOS-437 编码。
区分它们非常非常困难,可能需要通过实际检查每个超出字节 0x80 的编码范围产生正常的重音字符,以及您通常不会想到的特殊字符来完成在文件名中遇到。例如,许多 DOS-437 字符是用于在 DOS 中绘制半图形用户界面的框架。
供参考,这些是 DOS-437 中的特殊字符(因此字节范围为 0x80-0xFF):
80 ÇüéâäàåçêëèïîìÄÅ 90 ÉæÆôöòûùÿÖÜ¢£¥₧ƒ A0 áíóúñѪº¿⌐¬½¼¡«» B0 ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐ C0 └┴┬├─┼╞╟╚╔╩╦╠═╬╧ D0 ╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ E0 αßΓπΣσµτΦΘΩδ∞φε∩ F0 ≡±≥≤⌠⌡÷≈°∙·√ⁿ²■
并且在 Windows-1252 中:
80 €�‚ƒ„…†‡ˆ‰Š‹Œ�Ž� 90 �‘’“”•–—˜™š›œ�žŸ A0 ¡¢£¤¥¦§¨©ª«¬�®¯ B0 °±²³´µ¶·¸¹º»¼½¾¿ C0 ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ D0 ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß E0 àáâãäåæçèéêëìíîï F0 ðñòóôõö÷øùúûüýþÿ
其中一些甚至无法打印,因此它更容易一些。
如您所见,一般来说,DOS-437 的大部分重音字符位于 0x80-0xA5 区域(0xE1 处的 Beta 在德国通常用作 eszett),而 Win-1252 实际上有它们都在区域 0xC0-0xFF 中。如果您确定了这些区域,您可以建立一个扫描机制来评估它似乎倾向于哪种编码,只需计算每个区域落在预期范围内和之外的数量。
请注意,c# 中的 Char
表示一个 unicode 字符,无论它是从什么字节加载的,并且 unicode 字符具有某些分类,您可以通过编程方式查找这些分类以区分普通字母(可能带有变音符号) ) 和各种 类 特殊字符(简单示例:我知道其中一个 类 是 "whitespace characters")。可能值得研究该系统以自动确定 "normal language characters" 是什么的过程。