字符编码那些事

为什么需要Unicode编码?

世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。因此拥有一套统一的编码字符集来囊括世界上所有文字,对于互联网的推进起到了最重要的作用之一!

为什么有了Unicode之后,还需要UTF-8?

  1. 查看汉字Unicode字符集,我们可以看到一个汉字可能由两个字节、三个字节甚至更长的字节来表示。但是在最初的ASCII码中,一个字符用一个字节来表示足矣。当我们引入Unicode之后,对于当初最基本的拉丁文字符(A - Z),如果保持同样的字节长度势必会导致空间的浪费。因此需要一种变长存储的方案。
  2. 计算机如何才能区别 Unicode 和 ASCII?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?

Unicode只是一套编码字符集,只规定了一个字符用哪一个二进制代码来表示,并为规定这个二进制代码应该如何存储。而UTF-8为Unicode的落地提供了实现方案。那么UTF-8是如何考虑的呢?
UTF-8是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
编码规则:

  1. 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的
  2. 对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码

编码、解码?

字符==编码==写入磁盘
读取磁盘数据==解码==为字符

UTF8,UTF16区别?

UTF8采用变长的编码规则;而UTF16采用定长的编码规则,使用16位(2个字节)来表示一个字符。

Java中的码点、代码单元

码点:一个字符串在Unicode字符集中的编号(为一个十六进制数)。
代码单元:为了在计算机中表示一个Unicode字符的码点,每个码点可以编码为1个字节、2个字节、4个字节。代码单元就是指一个已编码的文本中具有最短的比特组合的单元。对于UTF-8(变长编码规则)来说,码元为8位、UTF-16(定长编码规则)而来,码元为16位

Java字符串由char值序列组成。char数据类型是一个采用UTF-16编码表示Unicode码点的代码单元。大多数的常用Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。

参考