位 / 字节 / 字符
位 ( bit ) : 计算机最小存储单位, 以二进制0和1表示
字节 ( Byte ) : 是基本计量单位 1byte = 8bit, 也就是说计算机以每字节也就是8位二进制数字进行储存, 换句话说只要写入至少是一个字节也就是8位二进制.
字符 ( Character ): 通常人们使用的一种记号, 是一种抽象意义上的符号实体
为什么 1 byte = 8 bit
早起出现过 4 6 7 位表示一个字节的编码, 私以为计算机是以2的次方表示大整数, 比如 2 4 8 16 , 位的概念在先 ascii 概念在后, 表示ascii表的全部符号至少需要用 7 位二进制, 后来因为推广的需要扩充至256 这时候至少要 8 位才能涵盖所有的ascii符号, 所以取2^3 = 8位表示一个字节比较通用
字符表 / 编码字符集 / 字符编码表 / 字符编码方案
字符表 ( Character repertoire ) : 一些抽象字符的集合
编码字符集 ( Coded Character Set ) : 给集合里面的每个抽象字符编上一个数字编号(字符码), 这种一一对应的映射关系构成编码字符集, Unicode 属于这一层级, 它与编码以及存储方式没有关系
字符码( Code Point ) : 字符码(Code Point)指的是字符集中每个字符的数字编号,例如 ASCII 字符集用 0-127 连续的128个数字分别表示128个字符,例如 “A” 的字符码编号就是65。
字符编码表( Character Encoding Form ) : 将映射的数字编号( 字符码 )按照某种编码规则转换成固定长度的比特值, 便于计算机以一定长度的二进制表示该整数, 这种对应的关系形成了字符编码表
字符编码方案( Character Encoding Scheme ) : 对于CEF得到的比特值具体如何在计算机中进行存储,传输。因为存在大端小端的问题,这就会跟具体的操作系统相关了。这种解决方案称为字符编码方案
常用字符集以及字符编码
常用字符集 : Ascii Big5 GBK GB2312 Unicode
常用字符集编码 : ascii big5 gbk gb2312 utf8
字节与字符之间的关系
大约多少个字节可以描述一个具体的字符, 根据编码的方式不同而不同, ASCII 中一个字节表示一个字符, GBK 中两个字节表示一个字符, UTF8 中3个字节表示一个汉字
我们看到的字 -> 字符 -> 字节 -> 位 他们之间的关系
计算机从硬盘读取二进制数据至内存, 此时并不知道这些二进制数据是以什么编码方式储存的, 因此我们需要自动或手动选择编码方式进行解码以方便接下来的操作, 如果选择的编码是 UTF8 那么将以这种编码进行解码成相应的字节数组, 但是也仅仅是一个数组这些自己具体表示什么内容并没有划分出多少字节为一个字符单位, 这个概念就相当于一个字节单位有八个比特,一个字符单位有几个字节的道理一样, 然而尽管划分了多少字节表示一个具体的字符, 也仅仅是一个Unicode中的数字编号(代码点)这些代码点需要映射成具体哪个字体中图形字符人类才可以正常阅读并识别
strings = '这是一个字符串'
# 转换成数组
bytes = strings.encode('utf-8')
# b'xe8xbfx99xe6x98xafxe4xb8x80xe4xb8xaaxe5xadx97xe7xacxa6xe4xb8xb2'
# 接下来我们看看他们的切片是以什么为单位的
strings[0] # "这" 这个字符其实是 xe8xbfx99 跟字体表映射后的图形
bytes[0] # 232 正好是十六进制的 xe8
讲讲Unicode 与 UTF8 之间的关系
Unicode 是编码字符集, 其实就是编了号的字符映射集合比如:
a -> 1
b -> 2
...
UTF8 是字符编码表, 它规定了Unicode集中编号( 字符码 )二进制的数据的转换关系, 比如:
# 对于字符“诗”,对应的UNICODE码点、UTF-XXX编码为:
CHAR : 诗
UNICODE: u+8bd7
UTF-8 : 0xe8af97
UTF-16 : 0x8bd7
UTF-32 : 0x00008bd7
# 他们是如何转换的
诗
UNICODE u+8bd7
对应二进制 10001011 11010111
按4/6/6分组 1000 101111 010111
UTF8的模板 1110xxxx 10xxxxxx 10xxxxxx
填充至模板 11101000 10101111 10010111
转换成十六进制 E8 AF 97
转换成十进制 232 175 151
python 中编码与解码
编码是指将字符串编码成字节流, 解码是指将字节流解码成字符串
strings = '诗'
# 以 UTF8 编码方式编码成 字节流
bytes = strings.encode('utf-8')
# 将字节流(数组) 解码成字符串
bytes.decode('utf-8')
# 最终得到的结果 : '诗'