为了账号安全,请及时绑定邮箱和手机立即绑定

UTF-8和UTF-8没有BOM有什么区别?

UTF-8和UTF-8没有BOM有什么区别?

UTF-8和UTF-8没有BOM有什么区别?UTF-8和UTF-8之间有什么不同BOM?哪种更好些呢?
查看完整描述

4 回答

?
紫衣仙女

TA贡献1839条经验 获得超15个赞

UTF-8 BOM是文本流(EF BB BF)开始时的字节序列,它允许读者更可靠地猜测文件是在UTF-8中编码的。

通常,BOM用来表示编码的endianness,但是由于endianness与UTF-8无关,所以BOM是不必要的。

查看完整回答
反对 回复 2019-06-01
?
BIG阳

TA贡献1859条经验 获得超6个赞

其他优秀的答案已经回答:

  • UTF-8和BOM-ed UTF-8之间没有正式区别。
  • BOM编辑的UTF-8字符串将以下三个字节开始.

    EF BB BF

  • 如果存在这些字节,则在从文件/流中提取字符串时必须忽略这些字节。

但是,作为这方面的附加信息,如果在UTF-8中编码了字符串,那么UTF-8的BOM可能是一种“嗅觉”的好方法.也可能是任何其他编码中的合法字符串.。

例如,数据[EF BB BF 41 42 43]可以是:

因此,虽然通过查看第一个字节来识别文件内容的编码是很酷的,但是您不应该依赖于这一点,如上面的示例所示。

编码应该是已知的,而不是预言。


查看完整回答
反对 回复 2019-06-01
?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

在UTF-8编码文件中放置BOM至少有三个问题.

  1. 不包含文本的文件不再是空的,因为它们总是包含BOM。
  2. 在UTF-8的ASCII子集中保存文本的文件不再是ASCII,因为BOM不是ASCII,这使得一些现有工具崩溃,用户可能无法替换这些遗留工具。
  3. 不可能将多个文件连接在一起,因为现在每个文件在开始时都有一个BOM。

而且,正如其他人所提到的,没有足够的、也没有必要的BOM来检测某些东西是UTF-8:

  • 这是不够的,因为任意字节序列可能会以构成BOM的确切序列开始。
  • 没有必要,因为您可以像读取UTF-8一样读取字节;如果成功,则定义为有效的UTF-8。


查看完整回答
反对 回复 2019-06-01
?
阿晨1998

TA贡献2037条经验 获得超6个赞

这是一个古老的问题,有许多好的答案,但有一件事应该补充。

所有的答案都很笼统。我想补充的是BOM使用的例子,它们实际上造成了真正的问题,但是很多人并不知道。

BOM破坏脚本

shell脚本、Perl脚本、Python脚本、Ruby脚本、Node.js脚本或任何需要由解释器运行的其他可执行文件

#!/bin/sh
#!/usr/bin/python
#!/usr/local/bin/perl
#!/usr/bin/env node

它告诉系统在调用这样一个脚本时需要运行哪个解释器。如果脚本是用UTF-8编码的,人们可能会在一开始就尝试包括一个BOM。但实际上“#!”人物不仅仅是人物。他们实际上是幻数它恰好由两个ASCII字符组成。如果你把一些东西(如BOM)放在这些字符之前,那么文件看起来就像有一个不同的神奇数字,这可能会导致问题。

Shebang字符由扩展的ASCII编码(包括UTF-8)中相同的两个字节表示,UTF-8通常用于当前类Unix系统上的脚本和其他文本文件。但是,utf-8文件可能以可选字节顺序标记(Bom)开头;如果“exec”函数专门检测字节0x23和0x21,则BOM(0xEF 0xBB 0xBF)的存在将阻止脚本解释器的执行。一些权威机构建议不要在POSIX(类Unix)脚本中使用字节顺序标记,[14]正是出于这个原因以及更广泛的互操作性和哲学考虑。此外,在UTF-8中,字节顺序标记是不必要的,因为编码不存在Endianness问题;它只用于将编码标识为UTF-8。[强调后加]

BOM在JSON中是非法的

实现不能在JSON文本的开头添加字节顺序标记。

BOM在JSON中是多余的

不仅是非法在JSON中,它也是不需要确定字符编码,因为有更可靠的方法可以明确地确定任何JSON流中使用的字符编码和endianness

BOM破坏JSON解析器

不仅是非法在JSON和不需要,实际上破坏所有软件中显示的方法来确定编码。

确定JSON的编码和endianness,检查NUL字节的前4个字节:

00 00 00 xx - UTF-32BE
00 xx 00 xx - UTF-16BE
xx 00 00 00 - UTF-32LE
xx 00 xx 00 - UTF-16LE
xx xx xx xx - UTF-8

现在,如果文件以BOM开头,则如下所示:

00 00 FE FF - UTF-32BE
FE FF 00 xx - UTF-16BE
FF FE 00 00 - UTF-32LE
FF FE xx 00 - UTF-16LE
EF BB BF xx - UTF-8

请注意:

  1. utf-32be不会以三个空开始,因此不会被识别。
  2. UTF-32LE第一个字节后面没有3个空号,因此不会被识别。
  3. 在前4个字节中,utf-16be只有一个NUL,因此不会被识别。
  4. 在前4个字节中,utf-16 le只有1个nul,因此不会被识别。

根据实施情况,所有这些可能被错误地解释为UTF-8,然后被误解或拒绝为无效的UTF-8,或者根本不被承认。

此外,如果像我建议的那样对有效的JSON进行实现测试,它甚至会拒绝输入,因为它不会像RFC那样以ASCII字符<128开头,因为输入确实编码为UTF-8。

其他数据格式

JSON中的BOM是不需要的,是非法的,并且破坏了根据RFC正确工作的软件。如果当时不使用JSON应该是个不需要考虑的问题,然而,总是有人坚持使用Boms、注释、不同的引用规则或不同的数据类型来破坏JSON。当然,如果需要的话,任何人都可以自由地使用Boms之类的东西-只是不要叫它JSON。

对于JSON以外的其他数据格式,请查看它的真实外观。如果唯一的编码是UTF-*,并且第一个字符必须是小于128的ASCII字符,那么您已经有了确定数据编码和编码的所有信息。即使将Boms添加为可选功能,也只会使其更加复杂和容易出错。

BOM的其他用途

至于JSON或脚本之外的使用,我认为这里已经有了非常好的答案。我想添加更多关于脚本和序列化的详细信息,因为这是BOM字符导致实际问题的一个例子。


查看完整回答
反对 回复 2019-06-01
  • 4 回答
  • 0 关注
  • 2970 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信