原标题:Java 字符编码
作者介绍
王云静,Java 开发工程师,2018 年 7 月加入去哪儿网,目前在目的地 - 呼叫中心。曾获得过 ACM 亚洲区域赛铜牌。
-----
基本概念 字符集
字符编码
字符编码(英语:Character encoding)也称字集码,是把字符集中的字符编码为指定集合中某一对象(例如:比特模式、自然数序列、8 位组或者电脉冲),以便文本在计算机中存储和通过通信网络的传递。
为了理解字符集和字符编码的关系,这里举个简单的例子,我们可以把字符集当成接口,把字符编码当成接口的实现。 Unicode是接口(字符集), UTF-8/ UTF-16/ UTF-32则是不同的实现(字符编码)。
ANSI
ANSI 全称(American National Standard Institite)美国国家标准学会(美国的一个非营利组织),首先 ANSI 不是指的一种特定的编码,而是不同地区扩展编码方式的统称,各个国家和地区所独立制定的兼容 ASCII 但互相不兼容的字符编码,微软统称为 ANSI 编码。
Unicode
Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
CodeUnit :代码单元/编码单元,是 Unicode 编码里一个 CodePoint 需要的最少字节数 例如:UTF-8 是一个字节,UTF-16 是两个字节,UTF-32 是四个字节
CodePoint :代码点,Unicode 规定的每一个字符就是一个 CodePoint
CodeSpace :代码空间,所有的代码点构成一个代码空间,根据 Unicode 定义,总共有 1,114,112 个代码点,编号从 0x0-0x10FFFF ,也就是大概 110 多万个字符
CodePlane :代码平面,Unicode 标准把代码点分成了17 个代码平面,编号为 #0-#16。每个代码平面包含 65,536(2^16)个代码点(17*65,536=1,114,112)。#0 叫做 基本多语言平面 (BMP:大部分常用的字符都坐落在这个平面内,比如 ASCII 字符,汉字等。代码点范围:0x0000-0xFFFF),其余平面叫做 补充平面
SurrogatePair :代理对,由一个 High-surrogate (高代理代码点: 0xD800-0xDBFF )和一个 Low-surrogate (低代理代码点: 0xDC00-0xDFFF )组成。这 2048 个代码点位于 BMP 内,并且不是有效的字符代码点,它们是为 UTF 编码保留的。在 UTF-16 中它可以编码 BMP 之外的代码点UTF-8
UTF-8 的特点是对不同范围的字符使用不同长度的编码。对于 0x00-0x7F 之间的字符,UTF-8 编码与 ASCII 编码完全相同。UTF-8 编码的最大长度是 4 个字节。
对于单个字节的字符,第一位设为 0,后面的 7 位对应这个字符的 Unicode 码点。
对于需要使用 N 个字节来表示的字符(N > 1),第一个字节的前 N 位都设为 1,第 N + 1 位设为0,剩余的 N - 1 个字节的前两位都设位 10,剩下的二进制位则使用这个字符的 Unicode 码点来填充。
Unicode 编码(十六进制)
UTF-8 字节流(二进制)
000000-00007F
0xxxxxxx
000080-0007FF
110xxxxx 10xxxxxx
000800-00FFFF
1110xxxx 10xxxxxx 10xxxxxx
010000-10FFFF
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
UTF-8 编码的最大长度是 4 个字节。从上表可以看出,4 字节模板有 21 个 x,即可以容纳 21 位二进制数字。Unicode 的最大码位 0x10FFFF 也只有 21 位。
UTF-16
UTF-16 是 Unicode 的一种编码方式,它用两个字节来编码 BMP 里的代码点,用四个字节编码其余平面里的代码点。
为了书写方便,我们把 Unicode 编码记作 U。
如果 U<0x10000 ,U 的 UTF-16 编码就是 U 对应的 16 位无符号整数。
为什么 U' 可以被写成 20 个二进制位?
Unicode 的最大码位是 0x10FFFF,减去 0x10000 后,U 的最大值是 0xFFFFF,所以肯定可以用 20 个二进制位表示。
UTF-32
UTF-32 编码以 32 位无符号整数为单位。Unicode 的 UTF-32 编码就是其对应的 32 位无符号整数。大/小端
大小端是 CPU 处理多字节数的不同方式,其主要特点是字节序在内存中存储位置不同。
大端(Big-Endian):高字节序存储在低地址,低字节序存储在高地址。