1.1 概述
字符集编码和解码是计算机处理文本数据的基础过程。这个过程涉及到两个主要的概念:字符集(Character Set)和字符编码(Character Encoding)。
-
字符集(Character Set):字符集是一个定义了一组字符和它们对应的数字的系统。例如,ASCII字符集定义了128个字符,包括英文字母、数字、标点符号等,每个字符都对应一个0到127之间的数字。
-
字符编码(Character Encoding):字符编码是一种将字符集中的字符转换为可以在计算机中存储和传输的二进制形式的方法。例如,ASCII编码就是一种字符编码,它将ASCII字符集中的每个字符编码为一个7位的二进制数。
编码过程是将字符转换为二进制数据的过程。在编码过程中,编码器首先查找字符在字符集中的数字,然后使用字符编码将这个数字转换为二进制数据。例如,如果我们使用ASCII编码,字符’A’在ASCII字符集中的数字是65,所以它被编码为二进制数据’1000001’。
解码过程是将二进制数据转换回字符的过程。在解码过程中,解码器首先使用字符编码将二进制数据转换回字符集中的数字,然后查找这个数字在字符集中对应的字符。例如,如果我们使用ASCII编码,二进制数据’1000001’被解码为数字65,然后查找ASCII字符集,找到数字65对应的字符是’A’。
需要注意的是,不同的字符集和字符编码可以表示不同的字符和数据范围。例如,UTF-8编码可以表示Unicode字符集中的任何字符,而ASCII编码只能表示ASCII字符集中的字符。因此,正确的解码一个二进制数据,需要知道它的字符集和字符编码。
1.2 常用字符集以占用空间大小
常用的字符集及其占用的空间大小如下:
-
ASCII:ASCII字符集包含128个字符,每个字符占用1个字节(8位)。
-
ISO-8859-1:也被称为Latin-1,包含256个字符,每个字符占用1个字节。
-
UTF-8:UTF-8是一种可变长度的Unicode编码格式,使用1到4个字节来表示一个字符。对于ASCII字符,UTF-8使用1个字节,对于拉丁文和希腊文等字符,UTF-8使用2个字节,对于其他平面的字符,UTF-8使用3或4个字节。
-
UTF-16:UTF-16也是一种可变长度的Unicode编码格式,使用2或4个字节来表示一个字符。对于基本多语言平面(BMP)中的字符,UTF-16使用2个字节,对于其他平面的字符,UTF-16使用4个字节。
-
UTF-32:UTF-32是一种固定长度的Unicode编码格式,每个字符占用4个字节。
-
GB2312:GB2312是一种简体中文字符集,包含6763个汉字和682个其他字符,每个字符占用1到2个字节。
-
GBK:GBK是GB2312的扩展,包含21886个汉字和883个其他字符,每个字符占用1到2个字节。
-
Big5:Big5是一种繁体中文字符集,包含13053个汉字和符号,每个字符占用1到2个字节。
以上是一些常见的字符集及其占用的空间大小,实际使用中,需要根据具体的应用场景和数据需求来选择合适的字符集。
字符集 | 描述 | 占用空间(字节) |
---|---|---|
ASCII | 包含128个字符 | 1 |
ISO-8859-1 | 也被称为Latin-1,包含256个字符 | 1 |
UTF-8 | 可变长度的Unicode编码格式 | 1~4 |
UTF-16 | 变长度的Unicode编码格式 | 2~4 |
UTF-32 | 固定长度的Unicode编码格式 | 4 |
GB2312 | 一种简体中文字符集 | 1~2 |
GBK | GB2312的扩展 | 1~2 |
Big5 | 一种繁体中文字符集 | 1~2 |
1.3 编码过程
编码器确定字符编码的过程主要依赖于字符集和字符编码方案。这个过程可以分为以下几个步骤:
-
首先,编码器会查找字符在字符集中的位置。字符集是一个定义了一组字符和它们对应的数字的系统。例如,ASCII字符集定义了128个字符,每个字符都对应一个0到127之间的数字。
-
然后,编码器会使用字符编码方案将字符集中的数字转换为二进制数据。字符编码是一种将字符集中的字符转换为可以在编码器中存储和传输的二进制形式的方法。例如,ASCII编码就是一种字符编码,它将ASCII字符集中的每个字符编码为一个7位的二进制数。
-
最后,编码器会将这个二进制数据存储在内存中或者通过网络传输。当需要读取这个字符时,编码器会使用相同的字符编码方案将二进制数据转换回字符集中的数字,然后查找这个数字在字符集中对应的字符。
1.4 解码过程
解码器确定编码对应的字符的过程主要依赖于字符集和字符编码方案。这个过程可以分为以下几个步骤:
- 首先,解码器会使用字符编码方案将二进制数据转换为字符集中的数字。字符编码是一种将字符集中的字符转换为可以在解码器中存储和传输的二进制形式的方法。例如,ASCII编码就是一种字符编码,它将ASCII字符集中的每个字符编码为一个7位的二进制数。
- 然后,解码器会查找这个数字在字符集中对应的字符。字符集是一个定义了一组字符和它们对应的数字的系统。例如,ASCII字符集定义了128个字符,每个字符都对应一个0到127之间的数字。
- 最后,解码器会将这个字符显示出来。
1.5 解码规则
一个字符经过编码后可能会输出多个字节,且字节间没有标识来区分,解码器是如何知道哪个或哪几个字节表示一个字符呢?举个例子,汉字“我”使用utf-8字符集编码,输出E68891(十六进制)或111001101000100010010001(二进制),解码时,解码器将编码的三个字节解码为一个字符,为什么不是将前两个字节解码为一个字符,后一个字节解码为一个字符呢或者前一个字节解码为一个字符,后两个字节解码为一个字符或者三个字节各解码为一个字符呢?
答:UTF-8编码是一种可变长度的编码方式,它使用1到4个字节来表示一个字符。对于UTF-8编码,每个字节的最高位都被用来表示这是一个字符的开始、中间还是结束。具体规则如下:
- 对于一个单字节的字符,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
- 对于n字节的字符(n > 1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
上述案例中,汉字“我”的UTF-8编码是E68891,它是一个三字节的字符。在解码时,首先看到E6(二进制表示为11100110),它的前三位是111,表示这是一个三字节的字符的开始,然后接下来的两个字节88(二进制表示为10001000)和91(二进制表示为10010001)的前两位都是10,表示这是一个字符的中间或者结束。
因此,通过查看每个字节的最高位,解码器就可以知道一个字符由多少个字节组成,从而正确地将字节组合成字符。