检测UTF-16文件内容

时间:2009-11-21 14:29:59

标签: file encoding utf-8 utf-16

是否可以知道文件是否包含Unicode(每个字符16个字节)或8位ASCII内容?

8 个答案:

答案 0 :(得分:8)

如果文件存在,可能能够阅读byte-order-mark

答案 1 :(得分:3)

与Brian Agnew所说的关于阅读byte order mark的内容是一致的,这是一个特殊的两个字节,可能出现在文件的开头。

您还可以通过扫描文件中的每个字节并查看它们是否都小于128来了解它是否为ASCII。如果它们都小于128,那么它只是一个ASCII文件。如果其中一些超过128,那么还有一些其他编码。

答案 2 :(得分:3)

UTF-16字符都至少为16位,有些是32位,右前缀(0xE000到0xFFFF)。因此,只需扫描每个字符以查看是否少于128将无效。例如,两个字节0x20 0x20将以ASCII和UTF-8编码两个空格,但以UTF-16编码为单个字符0x2020(匕首)。如果已知文本是英语,偶尔有非ASCII字符,那么大多数其他每个字节都将为零。但是如果没有关于文本和/或它的编码的一些先验知识,就没有可靠的方法来区分一般的ASCII字符串和一般的UTF-16字符串。

答案 3 :(得分:2)

首先,ASCII是7位,所以如果任何字节的高位设置,你就知道该文件不是ASCII。

各种“常见”字符集,如ISO-8859-x,Windows-1252等,都是8位,所以如果每隔一个字节为0,你知道你正在处理只使用ISO-8859字符。

在尝试区分Unicode和某些编码(如UTF-8)时,您会遇到问题。在这种情况下,几乎每个字节都有一个值,因此您无法做出简单的决定。正如Pascal所说,您可以对内容进行某种统计分析:阿拉伯语和古希腊语可能不会在同一个文件中。但是,这可能比它的价值更多。


编辑以回应OP的评论:

认为在您的内容中检查是否存在0值字节(ASCII NUL)就足够了,并根据它做出选择。原因是JavaScript关键字是ASCII,而ASCII是Unicode的子集。因此,这些关键字的任何Unicode表示形式都包含一个包含ASCII字符(低字节)的字节,另一个包含0(高字节)的字节。

我的一点需要注意的是,您仔细阅读文档以确保他们使用“Unicode”这个词是正确的(我查看了this page以了解该功能,但没有进一步了解。)

答案 4 :(得分:1)

如果您每次都需要解决此问题的文件足够长,并且某些想法它应该是什么(例如,unicode中的英文文本或ASCII中的英文文本) ,你可以对字符进行简单的频率分析,看看分布是否类似于ASCII或unicode。

答案 5 :(得分:1)

Unicode是字母表,而不是编码。你可能意味着UTF-16。有很多库(python-chardet立即想到)自动检测文本的编码,尽管它们都使用启发式。

答案 6 :(得分:1)

要以编程方式识别文件的类型(包括但不限于编码),最好的选择是使用libmagic。 BSD许可的它几乎是您将要遇到的每个Unix系统的一部分,但对于次要的系统,您可以将其与应用程序捆绑在一起。

例如,从C中检测mime类型很简单:

Magic = magic_open(MAGIC_MIME|MAGIC_ERROR);

mimetype = magic_buffer(Magic, buf, bufsize);

其他语言都有包装此库的自己的模块。

回到您的问题,这是我从file(1)libmagic(3)的命令行界面)中得到的信息:

% file /tmp/*rdp
/tmp/meow.rdp: Little-endian UTF-16 Unicode text, with CRLF, CR line terminators

答案 7 :(得分:0)

对于您的具体用例,很容易辨别。只需扫描文件,如果发现任何NULL(“\ 0”),它必须是UTF-16。 JavaScript必须具有ASCII字符,它们由UTF-16中的前导0表示。