29

我的程序必须读取使用各种编码的文件。它们可能是 ANSI、UTF-8 或 UTF-16(大端或小端)。

当 BOM(字节顺序标记)在那里时,我没有问题。我知道文件是 UTF-8 还是 UTF-16 BE 或 LE。

我想假设当没有 BOM 文件是 ANSI 时。但我发现我正在处理的文件经常缺少它们的 BOM。因此,没有 BOM 可能意味着文件是 ANSI、UTF-8、UTF-16 BE 或 LE。

当文件没有 BOM 时,扫描某些文件并最准确地猜测编码类型的最佳方法是什么?如果文件是 ANSI,我希望接近 100% 的时间,如果文件是 UTF 格式,我希望接近 100%。

我正在寻找一种通用的算法方法来确定这一点。但我实际上使用的是 Delphi 2009,它知道 Unicode 并且有一个 TEncoding 类,所以特定的东西将是一个奖励。


回答:

ShreevatsaR 的回答让我在 Google 上搜索“通用编码检测器 delphi”,这让我感到惊讶的是,这篇文章在仅存活了大约 45 分钟后就被列为第一名!那是快速的googlebotting!Stackoverflow 如此迅速地获得第一名也令人惊讶。

Google 中的第二篇文章是 Fred Eaker 撰写的关于字符编码检测的博客文章,其中列出了各种语言的算法。

我在那个页面上发现了 Delphi,它直接把我带到了 SourceForge 的 Free OpenSource ChsDet Charset Detector,它是用 Delphi 编写的,基于 Mozilla 的 i18n 组件。

极好的!感谢所有回答的人(全部 +1),感谢 ShreevatsaR,再次感谢 Stackoverflow,帮助我在不到一个小时的时间内找到答案!

4

4 回答 4

9

Maybe you can shell out to a Python script that uses Chardet: Universal Encoding Detector. It is a reimplementation of the character encoding detection that used by Firefox, and is used by many different applications. Useful links: Mozilla's code, research paper it was based on (ironically, my Firefox fails to correctly detect the encoding of that page), short explanation, detailed explanation.

于 2008-12-16T23:36:44.057 回答
5

这是记事本如何做到的

您还可以检查python 通用编码检测器。

于 2008-12-16T23:13:36.660 回答
4

我的猜测是:

  • 首先,检查文件的字节值是否小于 32(制表符/换行符除外)。如果是,则不能是 ANSI 或 UTF-8。因此 - UTF-16。只需要弄清楚字节序。为此,您可能应该使用一些有效的 Unicode 字符代码表。如果遇到无效代码,请尝试其他适合的字节序。如果适合(或不适合),请检查哪个具有较大百分比的字母数字代码。您也可以尝试搜索换行符并从中确定字节顺序。除此之外,我不知道如何检查字节顺序。
  • 如果文件不包含小于 32 的值(除了上述空格),它可能是 ANSI 或 UTF-8。尝试将其解析为 UTF-8 并查看是否有任何无效的 Unicode 字符。如果你这样做,它可能是 ANSI。
  • 如果您希望文档采用非英语单字节或多字节非 Unicode 编码,那么您就不走运了。您可以做的最好的事情是像 Internet Explorer 这样的东西,它制作字符值的直方图并将其与已知语言的直方图进行比较。它经常工作,但有时也会失败。而且您必须为每种语言拥有一个庞大的字母直方图库。
于 2008-12-16T23:11:08.710 回答
1

ASCII?现代操作系统不再使用 ASCII。它们至少都使用 8 位代码,这意味着它可以是 UTF-8、ISOLatinX、WinLatinX、MacRoman、Shift-JIS 或其他任何代码。

我知道的唯一测试是检查无效的 UTF-8 字符。如果你找到了,那么你就知道它不可能是 UTF-8。UTF-16 可能也是如此。但是当它没有设置 Unicode 时,就很难判断它可能是哪个 Windows 代码页。

我认识的大多数编辑器通过让用户从所有可能的编码列表中选择一个默认值来处理这个问题。

那里有用于检查 UTF 字符有效性的代码。

于 2008-12-16T23:10:07.633 回答