字符集和编码
ASCII字符集
不包含中文,0000 0000 - 0111 1111
优点占用空间小,缺点字符集内容少,只支持英文字符。
GBK编码(不定长)
为了支持中文的编码,在ASCII码的基础上做出的拓展,汉字两字节,普通字符一字节
汉字字符的开头必须是1,普通字符必须是0
汉字的范围:1000 0000 0000 0000 - 1111 1111 1111 1111
普通字符:0000 0000 - 0111 1111
在ASCII码的基础上支持中文编码,但问题是只支持中文和英文,别的国家的编码依旧不支持
Unicode字符集
国际组织为了保证世界编码的统一性提出的字符集,几乎包含了世界上所有的字符,理论上目前支持0x10FFFF个字符。
UTF-32(定长)
一个字符四个字节,完美的解决了编码不统一的问题,但是缺点是没人用。
UTF-16(不定长)
将字符编码成1个或2个双字节字符
- 0x0000-0xFFFF:基本多语言平面(BMP)一个双字节存储,存在保留位,没有完全使用
- 0x10000 - 0x10 FFFF:增补字符,两个双字节存储
BMP不做处理直接照搬,所以只需要关注增补字符的编码即可。
- 平移码点:首先减去0x10000,增补字符的范围变为0x0000-0xFFFFF,长度变为20位
- 拆分码点:将前10位放进高位代理,低10位放进低位代理,前六位都置0
- 平移高位代理:为了区分高位代理和BMP段,将高位代理平移到BMP中保留区域,加上0xD800
- 平移低位代理:为了区分低位代理和BMP段,将低位代理平移到高位代理之后,加上0xDC00
UTF-16的优点在于不识别前缀,一个字符传输时出错只影响一个字符,但不适合传输大量英文字符,是java默认的编码方式。
UTF-8(不定长)
一个字符的长度 | 编码格式 |
---|---|
一个字节 | 0xxx xxxx |
两个字节 | 110x xxxx 10xx xxxx |
三个字节 | 1110 xxxx 10xx xxxx 10xx xxxx |
四个字节 | 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx |
可以看到UTF-8最长的编码占四个字节其中支持的位数正好是21位,UTF-8在保证编码区间够用的同时尽可能节省了大量的空间,同时也是目前使用最多的编码方式,是C/C++默认的编码方式。
存在问题:存在严格的头部格式控制,如果数据传输中出现问题可能会造成大面积编码异常,因此数据如果以中文为主还是UTF-16更好。