今天学习了一下utf8的相关概念, 发现自己的理解还是不很透彻, 这里整理一下:
我们首先需要知道如何标识一个具体的字符, 国际上对于字符标识有一个东西, 叫UCS, 全称: Universal Character Set,
它是关于所有字符编码的标准. 简单地说, 为了能够规范我们所有字符的表示形式, 把所有字符都映射成一张表, 每个字符都指代单独的一个数字做标识.
上面的UCS只是表示字符的标识, 并没有说明具体的表示方式是什么. 所以就有了UTF-8, 用来把UCS转换成计算机能够处理的字符串. 它为了节省空间, 方便解析和除错做了优化. 具体表示方式如下:
- 小于u80的字符, 直接打印为一个字符, 这个是为了和ASCII标准兼容.
- 大于等于u80小于u800的字符, 分割成2个字符, 第一个字符开始为110, 第二个字符开始为10, 拆分的方法是先填满后面的字符(等会看后面的例子).
- 以此类推...
说的不是太清楚, 这里有一个UCS映射到UTF-8的表, 一看就明白了:
U-00000000 – U-0000007F: 0xxxxxxx U-00000080 – U-000007FF: 110xxxxx 10xxxxxx U-00000800 – U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx U-00010000 – U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx U-00200000 – U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx U-04000000 – U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
同时, 长的表示方式不能涵盖短的表示方式, 所以下面的范围是错误的(可以快速排除错误):
1100000x (10xxxxxx) 11100000 100xxxxx (10xxxxxx) 11110000 1000xxxx (10xxxxxx 10xxxxxx) 11111000 10000xxx (10xxxxxx 10xxxxxx 10xxxxxx) 11111100 100000xx (10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx)
我们来看具体的例子(python代码):
# 比如©这个符号, UCS的标识为: \u00a9:
>>> print u"\u00A9"
©
# 我们把a9转换成真正的表示方式:
>>> u"\u00A9".encode('utf8')
'\xc2\xa9'
# 我们也可以把真正的表示方式转换成标准里面的标识.
>>> '\xc2\xa9'.decode('utf8')
u'\xa9'
# 我们来看一个分割的例子:
>>> print u'\u2260'
≠
# 转换成utf8就被拆散了:
# u+2260 = 0010 0010 0110 0000
# 11100010 10001001 10100000 = 0xE2 0x89 0xA0
>>> u'\u2260'.encode('utf8')
'\xe2\x89\xa0'
现在还没有什么心得, 总之, 了解了上面的概念, 才能处理好平时遇到的字符编码问题.