字符编码(encoding),本质上是对所要表示的字符和二进制数据之间建立一种映射关系,就和查字典一样。
对问题的描述有不同的层次,有表示层次上,有传输层次上的。
中文编码:GB2312
- GB2312,又称为GB0,由中国国家标准总局发布,1981年5月1日实施
- GB2312标准共收录6763个汉字,其中一级汉字3755个,二级汉字3008个
- GB2312是一种区位码。分为94个区(01-94),每区94个字符(01-94)
- 01-09区为特殊符号
- 10-15区没有编码
- 16-55区为一级汉字,按拼音排序,共3755个
- 56-87区为二级汉字,按部首/笔画排序,共3008个
- 88-94区没有编码
- GB2312只是编码表,在计算机中通常都是用”EUC-CN”表示法,即在每个区位加上0xA0来表示。
- 区和位分别占用一个字节。GB2312的每个字符用两个字节表示
这里有一份GB2312简体中文码表。
比如汉字“君”,它在第30区,第93位。因此,“君”字用GB2312(或者说 EUC-CN)表示的话,第一个字节就是 30+0xA0 = 0xBE,第二个字节是 93+0xA0 = 0xFD,合在一起就是 0xBEFD。
中文编码:GB18030
GB18030,是中华人民共和国现时最新的内码字集。与GB 2312完全兼容,与GBK基本兼容,支持GB13000及Unicode的全部统一汉字,共收录汉字70244个。
- 与 UTF-8 相同,采用多字节编码,每个字可以由1个、2个或4个字节组成。
- 编码空间庞大,最多可定义161万个字符。
- 支持中国国内少数民族的文字,不需要动用造字区。
- 汉字收录范围包含繁体汉字以及日韩汉字
字节结构
- 单字节,其值从0到0x7F
- 双字节,第一个字节的值从0x81到0xFE,第二个字节的值从0x40到0xFE(不包括0x7F)
- 四字节,第一个字节的值从0x81到0xFE,第二个字节的值从0x30到0x39,第三个字节从0x81到0xFE,第四个字节从0x30到 0x39
由于GB 2312-80只收录了6763个汉字,有不少汉字,如部分在GB 2312-80推出以后才简化的汉字(如“啰”),部分人名用字(如中国前总理朱镕基的“镕”字),台湾及香港使用的繁体字,日语及朝鲜语汉字等,并未有收录在内。中文电脑开发商,于是利用了GB 2312-80未有使用的编码空间,收录了所有出现在Unicode 1.1及GB 13000.1-93之中的汉字,制定了GBK编码。
中文编码:GBK
由于GB2312只收录了6763个汉字,有不少汉字,如部分在GB 2312-80推出以后才简化的汉字(如“啰”),部分人名用字(如中国前总理朱镕基的“镕”字),台湾及香港使用的繁体字,日语及朝鲜语汉字等,并未有收录在内。中文电脑开发商,于是利用了GB 2312未有使用的编码空间,收录了所有出现在Unicode 1.1及GB 13000之中的汉字,制定了GBK编码。
GBK最初是由微软对GB2312的扩展,也就是CP936字码表。
虽然GBK收录了所有Unicode 1.1及GB13000之中的汉字,但是编码方式与Unicode 1.1及GB13000不同。仅仅是GB2312到GB13000之间的过渡方案。
参考资料:http://zh.wikipedia.org/zh-cn/GBK
中文编码: GB13000
GB 13000,全称 GB 13000.1-93,包含20,902个汉字,附录是GBK。
中文编码:GB12345
GB12345,全称《信息交换用汉字编码字符集 辅助集》,简称 GB1,于1990年发布,可以看成是GB2312的繁体版本,共收录6866个汉字。由于不能满足现实需求,所以也不被大多数电脑系统采用。
- 第01区到第09区和GB2312基本一样,并增加了6个汉语拼音字符和29个竖排标点。
- 第16区到第87区开始,排列和GB2312相对应的繁体字,如果GB2312中的汉字没有对应的繁体字,则排列和GB2312一样的汉字。
- 第88区到89区,增补了由于汉字简化而被精简的103个汉字
参考资料: http://zh.wikipedia.org/zh-cn/GB_12345
Unicode 与 UTF
Unicode 用两个或者四个字节来表示一个字符。理论上可以表示世界上所有的字符。
Unicode的基本多文种平面(Basic Multilingual Plane,简称BMP),每个字符占用2个字节(UCS-2)。理论上一共最多可以表示65536个字符。基本满足各种语言的使用。
最新(但未实际广泛使用)的Unicode版本定义了16个辅助平面,与BMP合起来至少需要占据21位的编码空间,比3字节略少,但事实上每个字符仍然占用4个字节(UCS-4)。
UCS或者UTF是用来描述如何传输这些字符。
UCS-2 & UCS-4
UCS-2 是用两个字节表示一个Unicode字符,UCS-4是用4个字节表示一个Unicode字符。
因为是用多于一个字符,所以也有所谓字节序 (Big-Endian 或者 Little-Endian) 的问题。为了区分不同的字节序,可以在文字文件最前面加上一个被称为BOM(Byte Order Mark)的特殊字符 0xFEFF 作为区分。0xFEFF字符在UNICODE中代表的意义是ZERO WIDTH NO-BREAK SPACE,顾名思义,它是个没有宽度也没有断字的空白。根据 字节序 中的描述,我们可以根据 BOM 的字节序来判断整个文件的字节序。
- 0xFE 0xFF: Big Endian (大尾)
- 0xFF 0xFE: Little Endian (小尾)
UTF-8 & UTF-16
UTF是Unicode Transformation Format的缩写。
UTF-8 使用一至四个字节为每个Unicode字符编码。其编码规则可以概括为两条:
- 单字节的符号,即 <= 0x7F 的字节,字节首位为0,后面7位为这个符号的unicode码。因此对UTF-8编码和ASCII码是相同的。
- 对于n字节的符号(n>1),首字节的前n位都设为1,第n+1位设为0,后面字节的前两位皆设为10。其余二进制位为这个符号的unicode码。
Unicode (十六进制) | UTF-8 (二进制) |
---|---|
0000 0000-0000 007F | 0xxxxxxx |
0000 0080-0000 07FF | 110xxxxx 10xxxxxx |
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
使用UTF-8的好处是对于西方的只包含ASCII字符的文件和软件,无须或只须做少部份修改,即可继续使用。
UTF-8没有字节序的问题,因些不需要 BOM(Byte Order Mark)。
UTF-16
UTF-16的编码规则如下:
Unicode (16进制) | UTF-16(二进制) | 字节数量 |
---|---|---|
0000 0000—0000 FFFF | xxxxxxxx xxxxxxxx | 2 |
0001 0000—0010 FFFF | 110110yyyyyyyyyy 110111xxxxxxxxxx | 4 |
根据以上规则,UCS-2可以看作是UTF-16的子集。对于小于 0xFFFFF的字符,UCS-2和UTF-16的编码结果是一样的。也正是因此,UTF-16也有所谓字节序的问题,也是通过BOM,用和UCS-2一样的方法来处理。
本文来自:http://noyesno.net/page/encoding/chinese