代码之家  ›  专栏  ›  技术社区  ›  Franck Freiburger

检测UTF-16文件内容

  •  6
  • Franck Freiburger  · 技术社区  · 15 年前

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

    8 回复  |  直到 6 年前
        1
  •  3
  •   Brian Agnew    11 年前

    布赖恩·阿格纽关于阅读 byte order mark ,可能出现在文件开头的特殊两个字节。

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

        2
  •  8
  •   Brian Agnew    15 年前

    可以 能够阅读 byte-order-mark ,如果文件中存在此项。

        3
  •  3
  •   Greg Young    9 年前

    UTF-16字符都是至少16位的,其中一些字符是32位的右前缀(0xe000到0xffff)。所以只需扫描每个字符,看看少于128个字符是否不起作用。例如,两个字节0x20 0x20将以ASCII和UTF-8编码两个空格,而以UTF-16编码一个字符0x2020(匕首)。如果知道文本是英语,偶尔使用非ASCII字符,那么大多数其他字节将为零。但是,如果没有关于文本和/或其编码的先验知识,就没有可靠的方法来区分通用的ASCII字符串和通用的UTF-16字符串。

        4
  •  2
  •   kdgregory    15 年前

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

    各种“通用”字符集(如ISO-8859-X、Windows-1252等)都是8位的,因此,如果其他每个字节都是0,则说明您所处理的Unicode只使用ISO-8859字符。

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


    根据OP的意见进行编辑:

    认为 这将足以检查内容中是否存在0值字节(ascii nul),并据此进行选择。原因是javascript关键字是ASCII,而ASCII是Unicode的一个子集。因此,这些关键字的任何Unicode表示将由一个包含ASCII字符的字节(低字节)和另一个包含0(高字节)组成。

    我的一个警告是,您仔细阅读文档以确保它们对“unicode”这个词的使用是正确的(我看了一下 this page 为了理解这个功能,没有进一步研究)。

        5
  •  1
  •   Pascal Cuoq    15 年前

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

        6
  •  1
  •   dottedmag    10 年前

    Unicode是字母表,不是编码。你可能是指UTF-16。有很多库(python chardet马上就会想到)可以自动检测文本编码,尽管它们都使用启发式方法。

        7
  •  1
  •   Mikhail T.    6 年前

    要以编程方式识别文件的类型(包括但不限于编码),最好使用 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
    
        8
  •  0
  •   ZZ Coder    15 年前

    对于您的特定用例,很容易分辨。只需扫描文件,如果您发现任何空值(“\0”),它必须是UTF-16。javascript必须有ASCII字符,它们由一个以utf-16表示的前导0表示。

    推荐文章