概念
Unicode: (
Universal Code
统一码)是一个囊括了世界上所有字符的字符集,其中每一个字符都对应有唯一的编码值(code point
),然而它并不是一种什么编码格式,仅仅是字符集而已Unicode
字符不管具体怎么编码和存储,可以用UTF-8
、UTF-16
来编码UTF-16
表示字符非常方便,每两个字节表示一个字符,这个在字符串操作时就大大简化了操作,这也是 Java 以UTF-16
作为内存的字符存储格式的一个很重要的原因UTF-8: (
Unicode Transformation Format
)就是在互联网上使用最广的一种Unicode
的实现方式(怎么编码,怎么存储)。其他实现方式还包括UTF-16
(字符用两个字节或四个字节表示)和UTF-32
(字符用四个字节表示)UTF-8
最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度
|
|
UTF-8编码
字符 | Unicode | UTF-8 | GBK |
---|---|---|---|
中 | 01001110 00101101(4e2d) | 01001110 00101101(e4b8ad) | 11010110 11010000(d6d0) |
UTF-8
常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4个字节.如果要传输的文本包含大量英文字符,用UTF-8编码就能节省空间:
|
|
「中」用 GBK 编码转后就是用2个字节表示,用 UTF-8 编码就是 3 个字节,同一个字符用不同的编码方式占用的字节长度可能不一。
编码规则
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode
码。因此对于英语字母,UTF-8
编码和ASCII
码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode
码。
|
|
如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。
BOM
BOM
:在一个文本文件或者一段字符编码前加上几个固定的字节用于识别,这些字节保证不对应任何一个字符,所以软件一读就能验明正身:
EF BB BF
-UTF-8
FF FE
-UTF-16LE
(Little endian
)FE FF
-UTF-16BE
(Big endian
)
以汉字「中」为例,Unicode
码是4e2d,需要用两个字节存储,一个字节是4e,另一个字节是2d。存储的时候,4e在前,2d在后,就是Big endian
(高位字节在前,阅读顺序)方式;2d在前,4e在后,就是Little endian
(低位字节在前)方式。Windows
的记事本还有Windows
其它地方所谓的Unicode
编码,其实是UTF-16LE
其他编码
ISO-8859-1
ISO-8859-1
仍然是单字节编码,它总共能表示 256 个字符。
GB2312
全称是《信息交换用汉字编码字符集 基本集》,它是双字节编码,总的编码范围是 A1-F7,其中从 A1-A9 是符号区,总共包含 682 个符号,从 B0-F7 是汉字区,包含 6763 个汉字。
GBK
为了扩展GB2312
,加入更多的汉字,它的编码范围是8140~FEFE
(去掉 XX7F)总共有 23940 个码位,它能表示 21003 个汉字,它的编码是和 GB2312
兼容的,也就是说用 GB2312
编码的汉字可以用 GBK
来解码,并且不会有乱码。
参考
https://stackoverflow.com/questions/3951722/whats-the-difference-between-unicode-and-utf-8