字符集与编码
编码与解码
编码:按照某种规则,将每一个字符用特定的二进制进行表示存储
解码:按照编码规则,将二进制数据解析成相应字符
符编码
1. ASCII编码
ASCII编码规定了128个字符的编码,使用了一个字节的后面7位(0000 0000~0111 1111),最高位规定为0;但在不同的国家有不同的字母,128个字符是不够的,因此,一些国家利用闲置的最高来表示一些新字符,这样就可以表示256个字符,如:在法语编码中1000 0010被用来表示é,而在其他语言编码中该二进制码可能表示不同的字符。
2. 非ASCII编码
ASCII编码只能表示一些英文字母或符号,对于英语国家而言是足够的,但对于其他语言来说,256个字符所能表示的字符则太少,如汉字仅常用字就有数千个,因此只能使用多个字节来表示,如GB2312就使用两个字节来表示一个汉字,理论上能表示256*256=65536个字符。
3. Unicode
不同的编码方式使得同一个二进制代码表示不同的字符,如果编码和解码使用的编码方式不一样,就会出现乱码的情况,这就需要一个全世界通用的编码方式,这个编码方式必须将全世界常用的字符纳入其中。
Unicode是只是一个符号集,规定了符号的二进制代码,并没有规定符号的存储方式,符号在计算机中怎样存储,是通过Unicode相应的实现决定的,如:utf-8、utf-16、utf-32
4. UTF-8
UTF-8采用变长编码,使用1~4个字节表示一个符号,UTF-8的编码规则如下:
(一):对于Unicode编码0000 0000~01111111之间的符号,采用单个字节存储,最高位设为0,即该编码方式与ASCII编码一致,UTF-8编码兼容ASCII编码
(二)对于Unicode编码1000 0000~0010 FFFF之间的符号,则采用第一个字节的前n位都设为1(n为字节数),第n + 1位设为0,后面字节的前两位一律设为10。其他的则为该符号的Unicode编码
(Unicode6.1定义了符号编码范围:0~10 FFFF)
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
即Unicode编码:
7个bit以下的,UTF-8使用一个字节 0xxxxxxx
8~11bit的,UTF-8使用两个字节,110xxxxx 10xxxxxx
12~16bit的,UTF-8使用三个字节,1110xxxx 10xxxxxx 10xxxxxx
17~21bit,UTF-8使用四个字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
UTF-8有BOM与无BOM:
(一)无BOM:直接是UTF-8的编码
(二)有BOM:EF BB BF UTF-8编码
BOM:字节顺序标记(如下UTF-16)
使用有BOM的方式进行编码,会在编码结果的最前面加上EF BB BF三个字节,EF BB BF其实是Unicode码FE FF的UTF-8编码,UTF-8编码不存在字节顺序问题,加上EF BB BF其实没有实际意义。
5. UTF-16/UCS-2(ISO标准)
使用两个字节表示符号,兼容ASCII编码,有些地方说的使用Unicode方式编码,其实指的是这一种编码方式,第一个字节为高位,第二个字节为低位,把高位放在前面为Big endian(大端方式),把低位放在前面为Little endian(小端方式)。那在文件中怎样区分是大端式,还是小端式呢?
Unicode规范,在每个文件的最前面加上一个表示编码顺序的字符(零宽度非换行空格),用 FE FF表示,如果是FE FF,则为大端方式,FF EF则是小端方式
6. UTF-32/USC-4(ISO标准)
UTF-32把所有的字符都用32bit也就是4个字节来表示
☆带上BOM其实是微软使用的,如果只在window上使用,则带上BOM不会出现问题,但如果在Linux等环境上使用带BOM的编码,可能会出问题,Unicode标准就是不带BOM的。
7.ANSI编码
ANSI编码其实是系统根据当前系统的区域(LOCAL)设置的,如果是中文(中国),则使用的是GBK编码,Korean(韩国),则使用EUC-KR编码,而English(英国),则使用的是ASCII编码
8.GBK编码
GBK编码,是对GB2312编码的扩展,因此完全兼容GB2312-80标准。GBK编码依然采用双字节编码方案,第一个字节范围是81~FE,第二个字节范围时 40-FE ,其中剔除xx7F码位,共23940个码位。共收录汉字和图形符号21886个,其中汉字(包括部首和构件)21003个,图形符号883个。
gbk介绍与编码表
UTF-16 的优缺点:
缺点
1.UTF-16 能表示的字符数有 6 万多,看起来很多,但是实际上目前 Unicode 5.0 收录的字符已经达到 99024 个字符,早已超过 UTF-16 的存储范围;
2.UTF-16 存在大小端字节序问题,如果字节序未处理好,将导致乱码;大小端的转换会耗费性能
3.容错性低有:局部的字节错误,特别是丢失或增加可能导致所有后续字符全部错乱,错乱后要想恢复,可能很简单,也可能会非常困难。
优点
双字节的,在计算字符串长度、执行索引操作时速度很快。当然这些优点 UTF-32 都具有,但很多人毕竟还是觉得 UTF-32 太占空间了。
UTF-8 的优缺点:
缺点
1.变长字节:无论是计算字符数,还是执行索引操作效率都不高。
优点
1.Unicode继续收录更多符号,UTF-8也可以进行兼容
2.不存在大小端字节序问题,信息交换时非常便捷
3.容错性高,局部的字节错误(丢失、增加、改变)不会导致连锁性的错误,因为 UTF-8 的字符边界(110xxx 10xxx)很容易检测出来。