UTF-8编码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
UTF-8 编码
作者:Marius Bancila,翻译:wangxg
字符集简史
在所有字符集中,最知名可能要数被称为 ASCII 的 7 位字符集了。它是美国信息交换标准委员会(American Standards Committee for Information Interchange)的缩写,为美国英语通信所设计。它由 128 个字符组成,包括大小写字母、数字 0-9、标点符号、非打印字符(换行符、制表符等 4 个)以及控制字符(退格、响铃等)组成。
但是,由于它是针对英语设计的,当处理带有音调标号(形如汉语的拼音)的欧洲文字时就会出现问题。因此,又创建出了一些包括 255 个字符的由 ASCII 扩展的字符集。其中有一种通常被成为 IBM 字符集,它把值为 128-255 之间的字符用于画图和画线,以及一些特殊的欧洲字符。另一种 8 位字符集是 ISO 8859-1 Latin 1,也简称为 ISO Latin-1。它把位于 128-255 之间的字符用于拉丁字母表中特殊语言字符的编码,也因此而得名。
欧洲语言不是地球上的唯一语言,因此亚洲和非洲语言并不能被 8 位字符集所支持。仅汉语(或 pictograms)字母表就有 80000 以上个字符。但是把汉语、日语和越南语的一些相似的字符结合起来,在不同的语言里,使不同的字符代表不同的字,这样只用 2 个字节就可以编码地球上几乎所有地区的文字。因此,创建了 UNICODE 编码。它通过增加一个高字节对 ISO Latin-1 字符集进行扩展,当这些高字节位为 0 时,低字节就是 ISO Latin-1 字符。UNICODE 支持欧洲、非洲、中东、亚洲(包括统一标准的东亚像形汉字和韩国像形文字)。但是,UNICODE 并没有提供对诸如 Braille,Cherokee,Ethiopic,Khmer,Mongolian,Hmong,Tai Lu,Tai Mau 文字的支持。同时它也不支持如 Ahom,Akkadian,Aramaic,Babylonian Cuneiform,Balti,Brahmi,Etruscan,Hittite,Javanese,Numidian,Old Persian Cuneiform,Syrian 之类的古老的文字。
事实证明,对可以用 ASCII 表示的字符使用 UNICODE 并不高效,因为
UNICODE 比 ASCII 占用大一倍的空间,而对 ASCII 来说高字节的 0 对他毫无
用处。为了解决这个问题,就出现了一些中间格式的字符集,他们被称为通用
转换格式,既 UTF(Universal Transformation Format)。目前存在的 UTF
格式有:UTF-7,UTF-7.5,UTF-8,UTF-16,以及 UTF-32。本文讨论 UTF-
8 字符集的基础。
UTF-8 字符集
UTF-8 是 UNICODE 的一种变长字符编码,由 Ken Thompson 于 1992 年创
建。现在已经标准化为 RFC 3629。UTF-8 用 1 到 6 个字节编码 UNICODE 字
符。如果 UNICODE 字符由 2 个字节表示,则编码成 UTF-8 很可能需要 3 个
字节,而如果 UNICODE 字符由 4 个字节表示,则编码成 UTF-8 可能需要 6
个字节。用 4 个或 6 个字节去编码一个 UNICODE 字符可能太多了,但很少会
遇到那样的 UNICODE 字符。
UFT-8 转换表表示如下:
UNICODE UTF-8
00000000 – 0000007F 0xxxxxxx
00000080 – 000007FF 110xxxxx 10xxxxxx
00000800 – 0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
00010000 – 001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
00200000 – 03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 04000000 – 7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
实际表示 ASCII 字符的 UNICODE 字符,将会编码成 1 个字节,并且 UTF-8
表示与 ASCII 字符表示是一样的。所有其他的 UNCODE 字符转化成 UTF-8 将
需要至少 2 个字节。每个字节由一个换码序列开始。第一个字节由唯一的换码
序列,由 n 位 1 加一位 0 组成。n 位 1 表示字符编码所需的字节数。
示例
UNICODE uCA(11001010) 编码成 UTF-8 将需要 2 个字节:
uCA -> C3 8A
UNICODE uF03F (11110000 00111111) 编码成 UTF-8 将需要 3 个字节:
u F03F -> EF 80 BF
译者注:由上分析可以看到,UNCODE 到 UTF-8 的转换就是先确定编码所需要的字节数,然后用 UNICODE 编码位从低位到高位依次填入上面表示为 x 的位上,不足的高位以 0 补充。以上是个人经验,如有错误,请不惜指教。
UTF-8 编码的优点:
UTF-8 编码可以通过屏蔽位和移位操作快速读写。字符串比较时 strcmp() 和wcscmp() 的返回结果相同,因此使排序变得更加容易。字节 FF 和 FE 在UTF-8 编码中永远不会出现,因此他们可以用来表明 UTF-16 或 UTF-32 文本(见 BOM) UTF-8 是字节顺序无关的。它的字节顺序在所有系统中都是一样的,因此它实际上并不需要 BOM。
UTF-8 编码的缺点:
你无法从 UNICODE 字符数判断出 UTF-8 文本的字节数,因为 UTF-8 是一种变长编码它需要用 2 个字节编码那些用扩展 ASCII 字符集只需 1 个字节的字符ISO Latin-1 是 UNICODE 的子集,但不是 UTF-8 的子集 8 位字符的 UTF-8 编码会被 email 网关过滤,因为 internet 信息最初设计为 7 为 ASCII 码。因此产生了 UTF-7 编码。 UTF-8 在它的表示中使用值 100xxxxx 的几率超过50%,而现存的实现如 ISO 2022,4873,6429 和 8859 系统,会把它错认为是 C1 控制码。因此产生了 UTF-7.5 编码。