一、介绍
UTF-8 是一套以 8 位为一个编码单位的可变长编码,会将一个码位(一个字符)编码为 1 到 4 个字节。
Unicode 是字符集,为每一个字符分配一个唯一的 ID(码位 / 码点 /编号),一个十六进制的码位,例如:“知”的码位是U+77E5。
UTF-8 是编码规则,将码位转换为字节序列的规则
二、原理
UTF-8 编码规则:
1、对于单字节的符号,字节的第一位(字节的最高位)设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2、对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
下表总结了编码规则,字母x表示可用编码的位。
Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制)
--------------------+---------------------------------------------
U+ 0000 ~ U+ 007F | 0XXXXXXX
U+ 0080 ~ U+ 07FF | 110XXXXX 10XXXXXX
U+ 0800 ~ U+ FFFF | 1110XXXX 10XXXXXX 10XXXXXX
U+10000 ~ U+1FFFF | 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX
示例1
根据上表中的编码规则,之前的「知」字的码位 U+77E5 属于第三行的范围:
7 7 E 5
0111 0111 1110 0101 二进制的 77E5
--------------------------
0111 011111 100101 二进制的 77E5
1110XXXX 10XXXXXX 10XXXXXX 模版(上表第三行)
11100111 10011111 10100101 代入模版
E 7 9 F A 5
这就是将 U+77E5 按照 UTF-8 编码为字节序列 E79FA5 的过程。反之亦然。
示例2
下面,再以汉字“严”为例,演示如何实现UTF-8编码:
“严”的Unicode编码:4E25
4:0100
E:1110
2:0010
5:0101
所以汉字“严”的二进制编码为:0100111000100101。
根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此“严”的UTF-8编码需要三个字节,即格式是“1110xxxx 10xxxxxx 10xxxxxx”。
从“严”的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。
这样就得到了,“严”的UTF-8编码是“11100100 10111000 10100101”,转换成十六进制就是E4B8A5。

三、代码
/// utf-8编码
- (NSString *)stringToUTF8:(NSString *)string
{
return [string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
}
/// utf-8解码
- (NSString *)utf8ToString:(NSString *)string
{
return [string stringByRemovingPercentEncoding];
}
网友评论