# 字符编码

  • 字符编码(Text Encoding):指将一个字符转换成其它字符,类似于转义字符的转码。
    • 常用于过滤掉某些不能直接处理的字符。
    • 例如一个 URL 只能由 ASCII 字符组成。如果要包含汉字字符,则必须转换成 URLencode 编码的字符。

# 编码分类

# BCD

:Binary-Coded Decimal(二进码十进数),是用 4 位二进制数表示一个十进制数 0~9 。

  • BCD 码常用于浮点数运算,可以保持数值的精度、减少运算耗时。
  • BCD 码分为多种类型,其中最常使用的是 8421BCD 码,它规定 4 位二进制数的位权分别为 8、4、2、1 。
    • 例如 0010 表示 2 ,1001 表示 9 。

# URLencode

:URL 编码,又称为百分号编码(Percent-encoding)。用于将 ASCII 编码的字符串转换成 URL 格式,并将 URL 中不允许使用的字符转码。

  • Python 的标准库 urllib 提供了 URLencode 的方法。

原理:

  1. 将字符串转换成 ASCII 编码。
  2. 将字符串中的每对键值对参数用 = 连接、键值对之间用 & 分隔。
  3. 根据 RFC 3986 规范进行转码:
    • URL 中只允许包含以下字符:
      • 数字 0-9
      • 英文字母 A-Za-z
      • 4 个特殊字符 -_.~
      • 保留字符 !*'();:@&=+$,/?#[] 。它们用于构成语法,用户也不应该直接使用。
    • 其它字符不能直接使用,要转换成百分号 % 加两位 16 进制编码。比如空格转换成 %20 ,! 转换成 %21 。

# Base64

:用于将二进制编码的字符串转换成由最多 64 种字符组成。

原理:

  1. 准备一个包含 64 种字符的索引表。比如:

    索引 字符
    0 A
    1 B
    2 C
    3 D
    4 E
    ... ...
  2. 将字符串转换成二进制编码。

  3. 从原数据中取出 3 个字节,拆分成 4 组,每组 6 个 bit 。

  4. 将每组的二进制值作为索引,转换成索引表中的对应字符。

  5. 重复 3-4 步骤,转换原数据的全部内容,组成一个字符串。

    • 如果最后一次只取出 1 个字节,则末尾补上 4 bit 的 0 ,得到 2 组。再加上 2 个等号 = 补成 4 组。
    • 如果最后一次只取出 2 个字节,则末尾补上 2 bit 的 0 ,得到 3 组。再加上 1 个等号 = 补成 4 组。
  • 标准的 Base64 索引表包含了 26 个大写字母 A-Z 、26 个小写字母 a-z 、10 个数字 0-9 、2 个特殊字符 +/ ,主要用于转义非 ASCII 字符、不可打印的 ASCII 字符。
  • 例:
    3 个字节:         A, B, C
    二进制编码为:        0100 0001 , 0100 0010 , 0100 0011
    拆分成 4 组之后为:   010000    , 010100    , 001001    , 000011
    十进制值为:          16, 20, 9, 3
    转换成索引表中的字符: Q , U, J, D
    

# Quoted-printable

:可打印字符引用编码。用于将 ASCII 编码的字符串转换成只剩可打印字符。

  • 常用于编码邮件内容。

原理:

  1. 将字符串转换成 ASCII 编码。
  2. 将字符串中的每个非可打印字符,用两个十六进制数表示,并加上等号 = 作为前缀。
    • 比如 = 要转换成 =3D
    • 每行字符串的末尾加上 = 作为分行符。
    • 每行字符串最多包含 76 个字符。

# import base64

:Python 的标准库,提供了 Base64 格式的编码、解码方法。

  • 用法示例:
    >>> import base64
    >>> base64.b64encode('hello'.encode())  # 先从 str 类型转换成 bytes 类型,再转换成 Base64 编码的 bytes 类型
    b'aGVsbG8='
    >>> base64.b64decode(_)
    b'hello'
    

# import quopri

:Python 的标准库,提供了 Quoted-printable 格式的编码、解码方法。

  • 用法示例:
    >>> import quopri
    >>> quopri.encodestring(b'hello world!==\r\n')
    b'hello world!=3D=3D\r\n'
    >>> quopri.decodestring(b'hello world!=3D=3D\r\n')
    b'hello world!==\r\n'