字符编码知识

来源:互联网 发布:韩顺平 linux视频教程 编辑:程序博客网 时间:2024/05/18 01:16

1. 字符编码模型

1.1抽象字符清单(ACR)

抽象字符清单(ACR)可以简单理解为无序的字符集合。在一个特定的标准中,清单可能会处于closed状态,意味着它是被修订过的,并且不会再追加了,或者也可能处于open状态,意味着新字符是可以随着时间的发展而增加的。例如,Unicode有一个开放的清单,会周期性的添加条目,目的是使得这个标准更加通用化。

例如:编码MyTest的acr={a,b,c,d,e}

1.2已编码字符集(CCS)

1)       定义

模型中的第二个层次是已编码字符集(CCS)。已编码字符集仅仅是从字符清单到唯一数字标识符的映射。一般来说,这些数字标识符指的是整数(在有些标准中是整数对)。

 数字标识符的专业术语叫做codepoint(码位),一个抽象字符和它的codepoint组合被称之为已编码字符。值得注意的是,这些codepoint与任何计算机中的表示无关。也就是说,这些codepoint并不是比特(字节),他们仅仅是整数。codepoint的取值范围常常是在标准中被限定了的。在一个编码标准中,有效的codepoint取值范围被称作codespace(编码空间)

(维基百科——编码空间(encoding space)的概念:简单说就是包含所有字符的表的维度。可以用一对整数来描述,例如:GB 2312的汉字编码空间是94 x 94。可以用一个整数来描述,例如:ISO-8859-1的编码空间是256。编码空间还可以用其子集来表述,如行、列、面(plane)等。编码空间中的一个位置(position)称为码位(code point)。一个字符所占用的码位称为码位值(code point value)。1个编码字符集就是把抽象字符映射为码位值。)

例如:编码MyTest的ccs={<a,1>,<b,2>b, <c,3>, <d,4>, < e,5> }

工业标准举例:ASCII,Unicode,GB2312-80(简体中文),CNS 11643(繁体中文),JIS X 0208(日文),KSX 1001(韩文)。这些标准是依赖于独立的编码表示。

2)       Unicode编码字符集

光是英语字符ASCII编码字符集是够了,但是如果算上世界上其他的语言的字符,ASCII码显然不够了,于是Unicode编码字符集应运而生。Unicode是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。Unicode的学名是"Universal Multiple-Octet CodedCharacter Set",简称为UCS。UCS可以看作是"Unicode Character Set"的缩写。

Unicode用数字0-0x10FFFF来映射这些字符(即0-0x10FFFF是Unicode的编码空间),最多可以容纳1114112个字符,或者说有1114112个码位(码位就是可以分配给字符的数字)。Unicode的编码空间可以划分为17个平面(plane),每个平面包含216(65,536)个码位。17个平面的码位可表示为从U+xx0000到U+xxFFFF,其中xx表示十六进制值从0016到1016,共计17个平面。第一个平面称为基本多语言平面(Basic Multilingual Plane, BMP),或称第零平面(Plane 0),包含了最常用的字符。其他平面称为辅助平面(Supplementary Planes)。基本多语言平面内,从U+D800到U+DFFF之间的码位区段是永久保留不映射到Unicode字符。

Unicode只是规定如何编码,并没有规定如何传输、保存这个编码。

1.3字符编码规则(CEF)

1)       定义

第三个层次是字符编码规则(CEF),从这个层次开始我们才真正开始涉及字符编码的计算机表示。CEF实际上是CCS中的codepoint到一系列固定数据类型序列的映射。这些映射后的值被称作code units(码元)。原则上,code unit可以是任意大小的:他们可以是7-bit,8-bit,19-bit,或者其他。最常用的当然是8/16/32 bits。

CCS和CEF之间的映射,即codepoint到code unit的映射并不一定非得是1对1的。在很多情况下,在编码规则中,一个codepoint可以映射多个code unit的序列。这种情况被称为“double-byte” 编码。例如microsoft的932 (Japanese Shift-JIS),950  (Traditional Chinese Big5)或GBK编码等。然而,有一件事情是很严格的:从给定的codepoint,到code unit的映射必须是唯一的。

例如:编码MyTest的cef:

可以用1B表示一个码元,用三个码元序列表示一个码位,则<a,1>表示为序列(0xFF,0xFF,0x01),<b,2>=(0xFF,0xFF,0x02)…< e,5> =(0xFF,0xFF,0x05);

也可以用3B表示一个码元,一个码元表示一个码位,则<a,1>=0xFFFF01,<b,2>=0xFFFF02… < e,5> =0xFFFF05;

2)       Unicode编码规则

Unicode已编码字符集可以使用三种编码规则进行表示。三种编码规则对应三种数据类型大小:UTF-8使用8-bit的code unit,UTF-16使用16-bit的code unit,UTF-32使用32-bit的code unit。其中,UTF-32可以使用一个单独的code unit表示每一个code point,但是UTF-8和UTF-16则使用一个或多个code unit的序列表示。

l        UTF-16与UCS-2的关系

Unicode编码空间中,从U+0000至U+D7FF以及从U+E000至U+FFFF的码位:

UTF-16与UCS-2编码这个范围内的码位为16比特长的单个码元,数值等价于对应的码位. BMP中的这些码位是仅有的可以在UCS-2中表示的码位.

Unicode编码空间中,从U+10000到U+10FFFF的码位:

辅助平面(SupplementaryPlanes)中的码位,在UTF-16中被编码为一对16比特长的码元(即32bit,4Bytes),称作代理对(surrogate pair)。

UTF-16可看成是UCS-2的父集。在没有辅助平面字符(surrogate code points)前,UTF-16与UCS-2所指的是同一的意思。但当引入辅助平面字符后,就称为UTF-16了。现在若有软件声称自己支持UCS-2编码,那其实是暗指它不能支持在UTF-16中超过2bytes的字集。对于小于0x10000的UCS码,UTF-16编码就等于UCS码。

l        Microsoft Windows操作系统内核对Unicode的支持

Windows操作系统内核中的字符表示为UTF-16小尾序,可以正确处理、显示以4字节存储的字符。但是Windows API实际上仅能正确处理UCS-2字符,即仅以2字节存储的,码位小于U+FFFF的Unicode字符。其根源是Microsoft C++语言把wchar_t数据类型定义为16比特的unsignedshort,这就与一个wchar_t型变量对应一个宽字符,可以存储一个Unicode字符的规定相矛盾。相反,Linux平台的GCC编译器规定一个wchar_t是4字节长度,可以存储一个UTF-32字符,宁可浪费了很大的存储空间。下例运行于Windows平台的C++程序可说明此点:

// 此源文件在Windows平台上必须保存为Unicode格式(即UTF-16小尾)

// 因为包含的汉字“

0 0
原创粉丝点击