目录标题
背景介绍
Character Set(字符集) 只是给所有的字符一个唯一编号
,但是却没有规定如何存储
。基于以上原因引入了字符编码
。
[Q&A] 什么是 UTF
UTF(Unicode Transformation Format)可译成Unicode格式转换,即怎样把Unicode对应的数字转换成程序数据。
[Q&A] Unicode 和 UTF-8 间有啥关系?
Unicode 和 Ascii 是字符集。UTF-8、UTF-16、UTF-32 等是编码规则。 可以通过编码规则将字符集的字符表示成程序中的数据。
# 例如:“汉字” 在不同编码下的程序数据
char data_utf8[] = {0xE6,0xB1,0x89,0xE5,0xAD,0x97}; //UTF-8编码
char16_t data_utf16[] = {0x6C49,0x5B57}; //UTF-16编码
char32_t data_utf32[] = {0x00006C49,0x00005B57}; //UTF-32编码
UTF-8 编码规则介绍
UTF-8 是一套以8位
为一个编码单位
的可变长编码。比如: 一个编号为65
的字符,只需要 1 个字节就可以存下,但是编号40657
的字符需要 2 个字节的空间才可以装下,而更靠后的字符可能会需要 3 个甚至 4 个字节的空间。
Unicode | Unicode对应二进制 | UTF-8字节流 | |
---|---|---|---|
单字节编码 | U+0000 - U+007F | 00000000 00000000 - 0000000 01111111 | 0xxxxxxx |
两字节编码 | U+0080 - U+07FF | 00000000 10000000 - 0000111 11111111 | 110xxxxx 10xxxxxx |
三字节编码 | U+0800 - U+FFFF | 00001000 10000000 - 11111111 11111111 | 1110xxxx 10xxxxxx 10xxxxxx |
四字节编码 | U+10000 - U+10FFFF | 00000001 00000000 00000000 - 00010000 11111111 11111111 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
Unicode Unicode对应二进制 UTF-8字节流
单字节编码 U+0000 - U+007F 00000000 00000000 - 0000000 01111111 0xxxxxxx
两字节编码 U+0080 - U+07FF 00000000 10000000 - 0000111 11111111 110xxxxx 10xxxxxx
三字节编码 U+0800 - U+FFFF 00001000 10000000 - 11111111 11111111 1110xxxx 10xxxxxx 10xxxxxx
四字节编码 U+10000 - U+10FFFF 00000001 00000000 00000000 - 00010000 11111111 11111111 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
举例:将 Unicode 按照 UTF-8 编码为字节序列
汉字: 知
Unicode码: 30693
Unicode码的十六进制表示为: 0x77E5
根据utf-8的上表中的编码规则,「知」字的码位U+77E5属于第三行的范围:所以需要3个字节(byte)
7 7 E 5
0111 0111 1110 0101 77E5对应的二进制的
--------------------------
1110XXXX 10XXXXXX 10XXXXXX 模版(由77E5范围,取上表第三行)
0111 011111 100101 根据模板格式调整77E5二进制的结构
11100111 10011111 10100101 代入模版
E 7 9 F A 5 转化回16进制
这就是将 U+77E5 按照 UTF-8 编码为字节序列 E79FA5 的过程。反之亦然。
[Q&A] 为啥不直接用UTF-32 ?
浪费空间
,假设使用UTF-32 和 ASCII 分别对一个只有西文字母的文档编码,前者需要花费的空间是后者的四倍
(ASCII 每个字符只需要一个字节存储)。故在 存储 和 网络传输 中,通常使用更为节省空间的“变长编码方式” UTF-8 。