字符集是一系列字符的集合,将每个收录的字符和数字进行映射。最早的字符集是ASCII,使用一个字节进行存储字符,8位一共可以表示256个字符,而ASCII只使用了其中的128位,即0~127位,这128位里面包括了常用的英文字符以及标点符号。
一部分不使用英文的字符可以用后面的128位来表示,即128~256位,后面的128位也被称为扩展字符集。但是它表示的字符有限,对于汉字来说,用单字节无法表示完整,因此国标码采用了双字节来表示汉字(即GBK等编码)。
由于不同国家的语言编码不同,互相之间如何通过ASCII进行交流?于是就有了万国码Unicode。Unicode是一个几乎包括了世上所有字符的字符集,每个字符都有一个对应的独一无二的Unicode码,比如聊天时使用的emoji表情字符,GitHub上也可以通过 :grin: 这种写法来输出emoji字符,这个对应的是😁。
因为Unicode使用四个字节来存储,虽然编码效率高,但是会极大浪费存储空间,因此就有了对Unicode字符集进行编码解码的存储方式,如UTF-8等字符编码。字符编码其实就是对Unicode字符集的实现方式,用以约定如何用1~4个字节来存储字符。
UTF-8是可变长编码,即多字节编码,在存储不同的字符时使用的字节数量是不同的。比如存储英文字母时只使用1个字节,而存储汉字时则使用3个字节。
UTF-8分为有BOM(Byte Order Marker)和无BOM的两种编码方式,现代文本编辑器在改变文件的编码时应该都看到过这两种编码。
UTF-8的好处是节省了空间,但编码效率降低了,即时间换空间。
UTF-16是双字节编码,属于定长编码。由于使用两个字节为一组来表示一个字符,那么就涉及到了字节顺序的问题,即大端小端的问题。这个是Mac机和PC机对字节顺序的理解不一致导致的历史遗留问题,机器在读取字节顺序时,会从低地址读取,将两个字节中的高位字节放在低地址表示,这就是大端BE,即big-endian。反之就是小端LE,即little-endian。
因此UTF-16存在三种编码:
FE FF
表示大端,FF FE
表示小端。使用UTF-16的好处是编码效率较高,但浪费存储空间,属于用空间换时间。
英文字母:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 编码:GB2312;字节数 : 1 编码:GBK;字节数 : 1 编码:GB18030;字节数 : 1 编码:ISO-8859-1;字节数 : 1 编码:UTF-8;字节数 : 1 编码:UTF-16;字节数 : 4 编码:UTF-16BE;字节数 : 2 编码:UTF-16LE;字节数 : 2 |
---|
中文汉字:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 编码:GB2312;字节数 : 2 编码:GBK;字节数 : 2 编码:GB18030;字节数 : 2 编码:ISO-8859-1;字节数 : 1 编码:UTF-8;字节数 : 3 编码:UTF-16;字节数 : 4 编码:UTF-16BE;字节数 : 2 编码:UTF-16LE;字节数 : 2 |
---|