字符编码
Posted 君自故乡来,应知故乡事
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符编码相关的知识,希望对你有一定的参考价值。
一、发展史
1、前提
字符编码只跟文本数据和字符串有关系,它跟视频文件、音频文件等无关
2、计算机只能识别二进制数,详解如下
二进制数即由0和1组成的数字,例如010010101010。计算机是基于电工作的,电的特性即高低电平, 人类从逻辑层面将高电平对应为数字1,低电平对应为数字0,这直接决定了计算机可以识别的是由0和1组成的数字
3、发展史
一家独大计算机最开始是有美国人发明的,他们肯定是想让计算机识别英文字符
ASCII码表:它的内部记录了英文字符和数字之间的关系
# ASCII码表内置使用一个字节代表一个字符
# 一个字节等于8位
0000001
2 ** 7 == 128
2 ** 8 == 256
在当初的时候,127种情况足够秒杀当时遇到的所有字符
后面使用8位代表一个字节是为了后续增加字符
需要记忆的是:
A-Z:65- 往后加一 a-z:97- 往后加一 0-9:48- 往后加一
字符串的比较:是按照ASCII码表的十进制数进行比较的
print(\'hello\' > \'world\')
中国人要想使用计算机,就自己开发了一套编码表:
GBK码表:它的内部记录了英文、中文和数字之间的对应关系
你----->129
好------>130
2 ** 16 == 65536
它还是使用一个字节保存英文字符
使用两个字节保存中文字符
日本人要想使用计算机,也得发明一套属于自己的编码表
Shift_JIS表
韩国人也要有一套属于自己的编码表
Euc-kr表一统天下
为了让世界上的所有国家之间能够彼此无障碍的交流,统一使用了编码
unicode(万国码)(在内存中)
# 它的内部是统一使用两个字节保存字符或者更多字符
由于原来的英文字符是使用一个字节保存的,现在万国码使用了两个字节,所以就把资源浪费了一倍
utf8编码(unicode的优化版本)
# 原来使用一个自己的英文字符,现在还使用一个字节保存 中文字符使用三个字节保存 2 **24 最终得出结论:以后在使用字符编码的时候就使用utf8 # 补充: utf-8、utf-16、utf-32...、utf8mb4(存表情)
二、python中的操作
1、 python解释器代码的差异
在python2中,默认使用的编码是ASCII码
# **-coding:utf-8-** s = u\'你好\' print s
python3中默认使用的是utf8编码
2、编码和解码
编码:是把其他字符串转为二进制的过程
str----->0101 str----->unicode----->0101001 ASCII---->GBK------>unicode----->utf8
解码:把二进制转为其他字符串的过程
s = \'hello你好哈\'
编码
res = s.encode(\'utf8\') # print(res) # b\'hello\' # 二进制 binary bin() print(res) # b\'hello\\xe4\\xbd\\xa0\\xe5\\xa5\\xbd\\xe5\\x93\\x88\'
解码
res1 = res.decode(\'utf8\') # gbk、utf8 print(res1) # hello你好哈 # 补充 s1 =b\'hello123\' # 只能是纯英文字符 s2=\'hello123\'.encode(\'utf8\')
Python 字符集编码 - UTF-8 编码
参考技术AUnicode 的编码范围为 0~0x10FFFF ,如此大的范围,显然没办法像 ASCII 编码一样使用一个字节存储。为此,Unicode 制定了各种储存编码的方式,如: UTF-8 、 UTF-16 和 UTF-32 ,这些存储格式被称为 Unicode 转换格式 UTF 。
每种 Unicode 转换格式都会把一个编码存储为一到多个编码单元,如 UTF-8 的编码单元为 8 位的字节; UTF-16 的编码单元为 16 位,即 2 个字节; UTF-32 的编码单元为 32 位,即 4 个字节。
其中, UTF-8 是在互联网上使用最广泛的一种 Unicode 转换格式,具有以下显著的优势。下面,我们就先来看看 UTF-8 具有哪些有点吧~
1. UTF-8 中每个 ASCII 字符只需要一个字节去存储,因此一个 ASCII 文本本身也是一个 UTF-8 文本,即做到了向后兼容。
比如 A 的 ASCII 码对应为 0x41 , a 的 ASCII 码对应为 0x61 ,那么 UTF-8 兼容 ASCII 也就意味着:
这里,需要再次提醒一下:Unicode 是表现形式,UTF-8 是存储形式;即 UTF-8 解码之后为 Unicode ,Unicode 可以编码成 UTF-8 。
2. UTF-8 采用字节为存储单元,因此不存在字节的大端和小段的问题。
UTF-16 和 UTF-32 的存储单元分别是 2 字节和 4 字节,因此在存储时会涉及到大小端的问题。那什么是大小端模式呢?下面我们来暂停补充一下~
关于如何获知你的环境使用的是大端模式还是小端模式,这里有个简单的方式:定义一个 short 类型的数组即可:
数字 1 在 short 类型中表示为 0x0001 ,高位为 0x00 ,低位为 0x01 。我们可以很直观地看到,数组在保存数据时,将高位 0x00 放在了高地址处,将低位 0x01 放在了低地址处。因此使用的就是小端模式。
那 UTF-8 为什么可以使用字节来作为存储单元,而不用担心字节序的问题呢?这就涉及到了 UTF-8 巧妙的编码规则~
UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用 1~4 个字节表示一个符号,根据不同的符号而变化字节长度。UTF-8的编码规则很简单,只有二条:
1)对于单字节符号,字节的第一位设为 0 ,后 7 位为这个符号的 Unicode 码。也就是我们上文提到的向后兼容:对于英文字母,UTF-8 编码和 ASCII 码是相同的。
2)对于使用 X 个字节存储的符号,第一个字节的前 X 位设置为 1 ,第 X+1 位设置为 0 ,后面字节的前 2 位一律设置为 10 ,剩下的位置一次填充这个符号的 Unicode 码。
下表总结了编码规则,字母 x 表示可用于编码的位:
跟据上表,解读 UTF-8 编码也非常简单:如果一个字节的第一位是 0 ,则这个字节单独就是一个字符;如果第一位是 1 ,则连续有多少个 1 ,就表示当前字符占用多少个字节。
下面,我们就来演示一下 UTF-8 编码的过程。
首先,获取汉字 鱼 的 Unicode 码:
我们不妨先对 鱼 这个汉字使用 utf-8 编码看看使用几个字节存储:
鱼 在 UTF-8 编码中使用 3 个字节存储,因此其存储的二进制的形式为 1110xxxx 10xxxxxx 10xxxxxx ,将 Unicode 1001 110001 111100 依次填充到占位符 x 的位置就得到: 11101001 10110001 10111100 。
下面,我们将上述推导得出的 11101001 10110001 10111100 转换为十六进制,验证一下是否为 b\'\\xe9\\xb1\\xbc\' :
验证无误!
以上是关于字符编码的主要内容,如果未能解决你的问题,请参考以下文章