猜测UTF-8编码

3

我有一个问题可能很幼稚,但我感觉需要问一下,因为我不太清楚发生了什么。 我正在使用Ubuntu操作系统。

假设我执行以下命令:

echo "t" > test.txt

如果我那时

file test.txt

I get test.txt:ASCII text

If I then do

echo "å" > test.txt

然后我得到:
test.txt: UTF-8 Unicode text

这是如何发生的?文件如何“知道”编码,或者说,它是如何猜测的?

谢谢。

4个回答

4
file manpage中得知:
如果一个文件不匹配在魔术文件中的任何条目,会检查它是否似乎是一个文本文件。ASCII、ISO-8859-x、非 ISO 8 位扩展 ASCII 字符集(例如 Macintosh 和 IBM PC 系统上使用的字符集)、UTF-8 编码 Unicode、UTF-16 编码 Unicode 和 EBCDIC 字符集可以通过构成每个集合中可打印文本的不同范围和序列的字节来区分。如果一个文件通过了这些测试中的任意一个,就会报告它的字符集。ASCII、ISO-8859-x、UTF-8 和扩展 ASCII 文件被标识为“text”,因为它们在几乎所有终端上都可以读取; UTF-16 和 EBCDIC 只是“字符数据”,因为尽管它们包含文本,但需要翻译后才能阅读。此外,file 还将尝试确定文本类型文件的其他特性。如果文件的行以 CR、CRLF 或 NEL 结束,而不是 Unix 标准的 LF,则会有相应的报告。同时也会识别包含转义序列或overstriking的文件。

谢谢。这是我需要的部分:“[utf-8] 可以通过构成可打印文本的不同字节范围和序列来区分”,那么究竟是什么区别它们? - Dervin Thunk
@DervinThunk:请查看UTF-8编码的描述 - DevSolar

4

存在某些字节序列,表明可能正在使用UTF-8编码(参见Wikipedia)。如果file发现其中一个或多个,并且没有发现任何在UTF-8中不可能出现的内容,则可以猜测该文件以UTF-8编码。但再次强调,这只是一种猜测。对于基本ASCII字符集(如't'这样的普通字符),在大多数常见的编码(包括UTF-8)中,其二进制表示相同,因此如果一个文件仅包含基本ASCII字符,则file无法确定预期使用的是哪个兼容ASCII的编码。它默认使用ASCII。

另一个需要注意的事项是您的shell设置为使用UTF-8,这就是为什么文件首先以UTF-8编写的原因。可以想象,您可以将shell设置为使用另一种编码,例如UTF-16,然后执行命令。

echo "å" > test.txt

将使用UTF-16编写文件。


你可能需要小心使用“对于基本ASCII字符集,二进制表示在所有编码中都相同”的说法。除了EBCDIC这样的老标准之外,在UTF-16或UTF-32中,那些基本的ASCII字符不再那么基本了。 - DevSolar

3
UTF-8是“ASCII友好”的,这意味着仅由ASCII字符组成的文本文件,无论是用ASCII还是UTF-8编码,均会完全相同。需要注意的是,有些人认为ASCII字符有256个,实际上只有128个。ISO-8859-x是一系列编码的家族,其中前128个字符是ASCII字符,而其余字符则是其他字符。
此外,UTF-8设计得非常好,并提供了多个属性。例如,某些字符采用1字节编码,另一些则采用2、3或4字节编码。但4字节字符永远不会包含任何较短字符的字节,3或2字节字符也是如此。所有1字节字符均使用0至127之间的字节进行编码,而所有较长字符均被编码为128至255范围内的字节序列。
非UTF-8字节流(例如二进制文件或UTF-16文件)通常可以排除为UTF-8,因为它很可能违反此类属性。唯一的例外是纯ASCII文件,当然可以安全地解释为UTF-8。
简而言之,UTF-8文件可以作为这样的文件检测出来,因为大多数“随机”的字节序列在UTF-8中都是非法的,因此不违反任何规则的东西 很可能 是UTF-8。

2

它在文件的开头插入了一个BOM(字节顺序标记)。

BOM可以告诉编辑器文件的编码以及大小端存储方式等信息。

你可以通过检查文件大小来确定是否存在BOM。如果文件大于2个字节(我猜测是4或5个字节),那么就有BOM。

这篇维基百科文章可以帮助你更好地了解BOM。


更新:

是的,我错了。

即使UTF-8也有BOM,但大多数编辑器不会在开头插入BOM,因为BOM代码与ASCII不兼容,而UTF-8的设计目标之一就是ASCII兼容性。因此,在UTF-8中插入BOM真的很糟糕!

因此,编辑器实际上猜测文件是否采用UTF-8编码。


那么另一个问题!:

似乎有可能编辑器猜测文件编码时出现错误。这种情况是否罕见?清楚地说,较小的文本更容易出现这种情况。


2
BOM并不是普遍使用的,如果没有它们,你只能猜测。 - Artelius
2
特别是,echo "å" > test.txt 可能不会在文件中插入BOM,因为echo不是设计用来创建文件的。 - Artelius
1
UTF-8 编码中的 BOM(字节顺序标记)长度为三个字节。但是不应该在 UTF-8 文件中使用 BOM,因为它们是无意义和非 ASCII 兼容的。不幸的是,一些 Microsoft 软件仍然会将它们添加到文件中。 - bobince
@bobince,@Dervin Thunk,@Artelius - 谢谢。我错了!=] - Isaac
1
BOM并非毫无意义。仅需查看前三个字节,它就能大大帮助检测UTF-8文件。如果一个文件没有BOM,你就必须更加费力地编写代码来读取整个文件并检查非ASCII字符。 - Ray Chakrit
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接