如何判断文件是Unicode(每个字符占16字节)还是8位ASCII码?
UTF-16字符都至少有16位,一些带有正确前缀(0xE000到0xFFFF)的字符是32位。因此,仅仅扫描每个字符以查看是否小于128是行不通的。例如,两个字节0x20 0x20会编码为ASCII和UTF-8中的两个空格,但在UTF-16中编码为单个字符0x2020(匕首)。如果文本已知为英语,偶尔出现非ASCII字符,则几乎每个其他字节都将为零。但是,如果没有关于文本和/或其编码的某些先验知识,则无法可靠地区分普通ASCII字符串和普通UTF-16字符串。
关于读取字节顺序标记,就像Brian Agnew所说的那样,有一个特殊的两个字节可能会出现在文件开头。
您还可以通过扫描文件中的每个字节并查看它们是否都小于128来知道它是否为ASCII。如果它们都小于128,则只是一个ASCII文件。如果其中一些大于128,则其中有其他编码。
根据OP的评论进行编辑:
我认为只需检查您的内容中是否存在0值字节(ASCII NUL),并基于此进行选择,就足够了。原因是JavaScript关键字是ASCII码,而ASCII码是Unicode的子集。因此,这些关键字的任何Unicode表示都将包含一个包含ASCII字符(低位)的字节和另一个包含0(高位)的字节。
我的一个警告是,您仔细阅读文档以确保他们对“Unicode”一词的使用是正确的(我查看了this page以了解该函数,没有进一步查看)。
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
Unicode是一个字母表,而不是一种编码方式。你可能想说的是UTF-16。有很多库可以自动检测文本的编码方式(比如python-chardet),但它们都使用启发式算法。
对于您的特定用例,很容易判断。只需扫描文件,如果找到任何NULL("\0"),它必须是UTF-16。JavaScript必须具有ASCII字符,并且它们由UTF-16中的前导0表示。