常⽤编码⽅式(ASCIIUnicodeGBK)
计算机中的数据都是按字节存储。⼀个字节(Byte)由8个⼆进制位组成(bit)组成(范围是0~255(2^8))
⼀个字节⼀共可以⽤来表⽰256种不同的状态,每⼀个状态对应⼀个符号,就是256个符号,从00000000到11111111。
本⽂中谈到的关系编码如下图所⽰:
1 ASCII码
ASCII 码对英语字符与⼆进制位之间的关系,做了统⼀规定。
ASCII 码⼀共规定了128个字符的编码,如空格SPACE是32(⼆进制00100000),数字0是48(⼆进制00110000)⼤写的字母A是
65(⼆进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占⽤了⼀个字节的后⾯7位,最前⾯的⼀位统⼀规定为0。
ASCII码在其他语⾔的情况下并不适⽤,⽐如汉字有10万个字符,所以有了其他的编码⽅式
2 Unicode
世界上存在着多种编码⽅式,同⼀个⼆进制数字可以被解释成不同的符号。因此,要想打开⼀个⽂本⽂件,就必须知道它的编码⽅式,否则⽤错误的编码⽅式解读,就会出现乱码,因此Unicode应运⽽⽣。
Unicode,就像它的名字都表⽰的,这是⼀种所有符号的编码,将世界上所有的符号都纳⼊其中,每⼀个符号都给予⼀个独⼀⽆⼆的编码。
Unicode存在的问题:
Unicode 只是⼀个符号集,它只规定了符号的⼆进制代码,却没有规定这个⼆进制代码应该如何存储。 如果 Unicode 统⼀规定,每个符号⽤三个或四个字节表⽰,那么每个英⽂字母前都必然有⼆到三个字节是0,这对于存储来说是极⼤的浪费。
为了解决这个问题:就有了Unicode 三种实现:UTF8 UTF16 UTF32
UTF8可以⽅便的转换为UTF16和UTF32
2.1 UTF-8
UTF-8 就是在互联⽹上使⽤最⼴的⼀种 Unicode 的实现⽅式。其他实现⽅式还包括 UTF-16(字符⽤两个字节或四个字节表⽰)和 UTF-32(字符⽤四个字节表⽰)。UTF-8 是 Unicode 的实现⽅式之⼀。
UTF-8 最⼤的⼀个特点,就是它是⼀种变长的编码⽅式。它可以使⽤1~4个字节表⽰⼀个符号,根据不同的符号⽽变化字节长度。
UTF-8 的编码规则很简单,只有⼆条:
1)对于单字节的符号,字节的第⼀位设为0,后⾯7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。
PS:⾼位为1和10就区分了ascii码和UTF-8码
2)对于n字节的符号(n > 1),第⼀个字节的前n位都设为1,第n + 1位设为0,后⾯字节的前两位⼀律设为10。剩下的没有提及的⼆进制位,全部为这个符号的 Unicode 码。
下表总结了编码规则,字母x表⽰可⽤编码的位。
计算Unicode码字节数时时需要少算⼀位(因为单字节范围是0~127,超过127的都需要⽤2个字节表⽰了)
正如表中范围:第⼀个字节有效返回只在00000000 - 0000007F之间(2^0-2^7-1)。
所以后⾯字节有饭范围均为后推.如2字节有效返回00000800 - 000007FF(2^7-2^15-1)
李(Unicode 编码 674E) 在第三⾏范围内(00000800 - 0000FFFF)
即UTF-8编码框架为:1110xxxx 10xxxxxx 10xxxxxx
李的unicode 码2进制表⽰: 0110 0111 0100 1110 (前⾯的0要补上凑够2字节 110 0111 0100 1110 -> 0110 0111 0100 1110)
将2机制填⼊到UTF-8编码中得到UTF-8的2进制:
11100110 10011101 10001110
UTF-8 编码16进制:E69D8E
2.2 UTF-16
UTF-16 使⽤⼆或四个字节为每个字符编码(定长 ⼀般情况下为2字节),因为对于绝⼤部分字符只使⽤2个字节就可以表⽰了。对于汉字⽽⾔,⼤部分汉字采⽤两个字节编码,少量不常⽤汉字采⽤四个字节编码。⽽UTF-16同样存在⼤⼩端的问题, UTF-16BE 和 UTF-16LE,在编码前会放置⼀个 U+FEFF 或 U+FFFE(UTF-16BE 以 FEFF 代表,UTF-16LE 以 FFFE 代表).也就是2.1中Unicode 中编码头
2.3 UTF-32
java语言使用的字符码集是UTF-32 使⽤四个字节为每个字符编码,使得 UTF-32 占⽤空间通常会是其它编码的⼆到四倍。UTF-32 与 UTF-16 ⼀样有⼤尾序和⼩尾序之别,编码前会放置 U+0000FEFF 或 U+0000FFFE 以区分。
2.4 unicode 中BOM
Unicode编码中表⽰字节排列顺序的那个⽂件头,叫做BOM(byte-order mark).
2.4.1 unicode ⼤⼩端问题
Unicode 规范定义,每⼀个⽂件的最前⾯分别加⼊⼀个表⽰编码顺序的字符,这个字符的名字叫做”零宽度⾮换⾏空格”(zero width
no-break space),⽤FEFF表⽰。
如果⼀个⽂本⽂件的头两个字节是FE FF,就表⽰该⽂件采⽤⼤端⽅式(674E 正常顺序即为⼤端);如果头两个字节是FF FE,就表⽰该⽂件采⽤⼩端⽅式(4E67 正常顺序即为⼤端)。
2.4.2 unicode 不同实现的BOM
UTF-8⽂件的BOM是“EF BB BF”,但是UTF-8的字节顺序是不变的,因此这个⽂件头实际上不起作⽤。有⼀些编程语⾔是ISO-8859-1编码,所以如果⽤UTF-8针对这些语⾔编程序,就必须去掉BOM,即保存成“UTF-8—⽆BOM”的格式才可以.
UTF-16 BOM 即为FEFF 或者FFEF ⽤于解决⼤⼩端问题
UTF-32BOM 为 U+0000FEFF 或 U+0000FFFE 以区分
3 中⽂编码
注意这⾥说的中⽂编码和unicode 编码没有关系
3.1GB2312
GB2312⼜称国标码,由国家标准总局发布
GB2312规定“对任意⼀个图形字符都采⽤两个字节表⽰,每个字节均采⽤七位编码表⽰”,习惯上称第⼀个字节为“⾼字节”,第⼆个字节为“低字节”。GB2312中汉字的编码范围为,第⼀字节0xB0-0xF7(对应⼗进制为176-247),第⼆个字节0xA0-0xFE(对应⼗进制为160-254)。
3.2 GBK
GBK是GB2312的扩展,是向上兼容的,因此GB2312中的汉字的编码与GBK中汉字的相同。另外,GBK中还包含繁体字的编码.
4 常⽤语⾔中编码类型
以下讨论均为程序内编码
Java : Unicode characters(UTF-16)
JavaScript: UTF-16的格式储存。
C/C++:字符串常量指的是窄字符(char)(UTF-8)。宽字符(wchar_t)通常是以Unicode(VC使⽤UTF-16BE,gcc使⽤UTF-32BE)存放。
Python2: 默认ASCII编码。Python中字符串类型有str 和Unicode两种。
Linux操作系统: UTF32
window平台: UTF16
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论