ANSI, Unicode, UTF, endian, GB2312, GBK - BOM, UCS

创建时间:
2014-03-01 11:18
最近更新:
2018-09-04 15:29

Resource - MSDN

  1. System.BitConverter 类 - Converts base data types to an array of bytes, and an array of bytes to base data types.
  2. System.BitConverter.IsLittleEndian 字段 - Indicates the byte order ("endianness") in which data is stored in this computer architecture.

Abbreviation

  • BOM (Byte Order Mark, 字节顺序标记)
  • UCS (Universal Character Set, 通用字符集)

BOM

Unicode 统一使用 2 个字节来表示所有字符 (共 65536 个码位),原 ASCII 编码置于低 8 位中、增加的高 8 位全部是 0。

在网络上交换 Unicode 数据时,
INTEL 架构采用低位先发送的方案,
而其它架构采用高位先发送的方案。
标识方法:
在文本流前增加 BOM ——如果之后的文本是高位在前则增加 FEFF,反之则增加 FFFE

BOM 清单

endian BOM
UTF-8 EF BB BF
UTF-16/UCS-2 big endian FE FF (正序,例如 ab 表示为 0061 0062)
UTF-16/UCS-2 little endian FF FE (逆序,例如 ab 表示为 6100 6200)
UTF-32/UCS-4 big endian 00 00 FE FF
UTF-32/UCS-4 little endian FF FE 00 00

Example

以下代码创建一个 3字节 的 空文本文件:

var fs = new System.IO.FileStream(@"d:/test.txt", System.IO.FileMode.Create);
var bytes = new byte[] { 0xef, 0xbb, 0xbf };
fs.Write(bytes, 0, 3);
fs.Close();

其中的 0XEF, 0XBB, 0XBF 代表 UTF-8 编码的文件头。普通的 ANSI 编码不需要文件头,所以空文本文件为 0字节。

NotePad 共有 4 种编码选择

ANSI 不增加任何 BOM,这导致使用系统默认编码,在汉语操作系统中通常使用 GB 系列编码)。
Unicode 自动增加 BOM "FF FE" (这意味着 little endian)。
Unicode big endian 自动增加 BOM "FE FF"。
UTF-8 自动增加 BOM "EF BB BF"。

在 VisualStudio 中查看 BOM 的方法之一

解决方案资源管理器 » 需查看的文件 » 右键 » 打开方式 » 二进制编辑器。

ZERO WIDTH NO-BREAK SPACE (零宽度非换行空格)

在 UCS 编码中有一个叫做 "ZERO WIDTH NO-BREAK SPACE" 的字符,它的编码是 FEFF
FFFE 在 UCS 中是不存在的字符,所以不应该出现在实际传输中。
UCS 规范建议我们在传输字节流前,先传输字符 "ZERO WIDTH NO-BREAK SPACE"。
这样如果接收者收到 FEFF,就表明这个字节流是 Big-Endian 的;
如果收到 FFFE,就表明这个字节流是 Little-Endian 的。
因此字符 "ZERO WIDTH NO-BREAK SPACE" 又被称作 BOM。

UTF-8 不需要 BOM 来表明字节顺序,但可以用 BOM 来表明编码方式。
字符" ZERO WIDTH NO-BREAK SPACE" 的 UTF-8 编码是 EF BB BF。
所以如果接收者收到以 EF BB BF 开头的字节流,就知道这是 UTF-8 编码了。
Windows 就是使用 BOM 来标记文本文件的编码方式的。

Vim 设置 UTF-8 编码的 BOM 标记

Solution 1

:help bomb //help
:set bomb? //query current setting of BOM
:set nobomb //remove BOM
:set bomb //add BOM

Solution 2

以十六进制模式打开文件、删除 BOM、退出十六进制模式。

:%!xxd //convert to HEX
:%!xxd -r //convert back from HEX

Resource

  1. 理解字节序
  2. http://iekilled.us/vim/2012/05/03/vim-strip-bom.html