参考文章,感谢:
彻底理解字符编码
ANSI是什么
细说:Unicode, UTF-8, UTF-16, UTF-32, UCS-2, UCS-4)
Unicode 和 UTF-8 之间的关系
几种编码方式的对照表
名称 | 别名 | 编码字符个数 | 编码字符范围 | 编码所用字节数 | 编码规则 |
---|---|---|---|---|---|
ASCII | 128 | 0~9,大小写英文字母,常 用符号和特殊控制符 |
1byte(8bit),实际只用7bit 最高位统一规定为0 |
最高位做奇偶校验 | |
IOS-8859-1 | Latin-1 西欧编码 |
256 | 在ASCII基础上从128~255又 编码了一些西欧语言字母 |
1byte(8bit) | 有较多协议默认使用该编码,虽然 中文(2字节)无法用该编码表示, 但可拆分存储再组合还原。如‘中’GB2312编码为0xd6d0,可拆为0xd6,0xd0 |
GB3212 | 7445 | 简体中文和其他字符; 01-09区:收录除汉字外的682个字符,包含164个空字符(9*94-682); 10-15区,88-94区为空白区,没使用; 16-55区收录3755个一级汉字,按拼音排序; 56-87区收录3008个二级汉字,按部首,笔画排序 |
2byte,682个其他字符包括拉丁字母,希腊 字母,日文平假名,片假名字母,俄语西里尔字母 |
汉字的编码范围0xB0A1-0xF7FE, GB2312区位码转GB2312编码规则见下 |
|
BIG5 | 13060 | 繁体中文(有2个汉字为重复编码)和其他符号 | 2byte | 高字节:0x81-0xFE 低字节:0x40-0x7E | |
GBK | 21003 | 在GB2312的基础上扩展,增加了繁体字的编码,但编码值和BIG5中不同 | 2byte | 23940个码位 | |
Unicode | – | 11141112 | 地球上所有字符,每个字符都能找到对应的码点(code point) | 0x000000-0x10FFFF | 编码方法较复杂,略 说明:Unicode仅仅是一个符号集, 只规定了字符对应的码点,没有规定存储方式,由Unicode分出两种存储方案USC和UTF |
UCS | UCS-2 | 2byte | 采用BOM(byte order mark),确定字节流采用大端序,还是小端序,确定字节流的编码方案 | ||
UCS-4 | 4byte | 采用BOM | |||
UTF | UTF-8 | 完全兼容ACII | 1~4byte,变长编码,有利于节省网络流量,应用广泛 | Unicode码点转化为UTF-8编码规则见下面介绍 | |
UTF-16 | 2或4byte | 较复杂,略 | |||
UTF-32 | 4byte | ||||
ANSI | Windows系统本地默认编码 | Mac和Linux系统默认编码为UTF-8 | ANSI不是某种特定编码,Windows在美国ANSI码表示ASCII码,在中国大陆ANSI表示GBK,在中国台湾表示BIG-5,在韩国表示EUC-KR等 | Windows系统的文本编辑器默认编码为ANSI | 在0x00-0x7F之间的字符任然用一个字符表示,即兼容ASCII码,超出该范围的字符才采用本地编码,如GB2312等 |
ANSI编码的bug:
当输入“联通”并用ANSI编码保存并再打开时会乱码。因为当字符编码在C0<=AA<=DF,80<=BB<=BF,在这个范围,编辑器无法确定字符的编码方式,编码重合字段,不同的编码方式,对应不同的字符。“联通”的编码为C1 AA CD A8。
Unicode码点转化为UTF-8编码规则:
Unicode符号范围 | UTF-8编码方式 |
---|---|
0000 0000 - 0000 007F(0~127) | 0XXX XXXX |
0000 0080 - 0000 07FF(128~2047) | 110XXXXX 10XXXXXX |
0000 0800 - 0000 FFFF(2048~65535) | 1110XXXX 10XXXXXX 10XXXXXX |
0001 0000 - 0010 FFFF(65535~1114111) | 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX |
例如:中文‘李’的Unicode码点为26446(十进制),二进制为0110 0111 0100 1110,十六进制为0x674E,根据上表,得到UTF-8编码1110 0110 10011101 10001110即0xE69D8E
GB2312区位码转编码的规则:
(区码转为十六进制+0xA0) +(位码转为十六进制+0xA0) = GB2312编码
例如:‘李’的区位码为3278(32区,78位),32 = 0x20,78 = 0x4E
0x20 + 0xA0 = C0; 0x4E + 0xA0 = 0xEE,所以‘李’的GB2312编码为C0EE