编码:Base64


Base64编码

参考文章:

[1] Base-x 编码的奥秘 - 知乎 (zhihu.com)

[2] Base编码(贝斯家族)_MikeCoke的博客-CSDN博客_base编码


0x00 Base64编码简介

顾名思义,就是基于64个可打印字符来表示二进制数据的一种方法。(它不是加密算法)。对于64个打印字符,我们字需要6个二进制位就可以完全表示了。

那么我们如何利用8个二进制位来表示只需要6个二进制位就可以完全表示的可打印字符呢?由于2的6次方等于64,所以我们可以将每6个位元为一个单元,对应某个可打印字符。三个字节有24个位元,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示(一般的ASCII码中一个字符有8位,但在这64个字符中只需要6位就可以表示出来了)。它可用来作为电子邮件的传输编码。

在Base64中的可打印字符包括字母A-Z、a-z、数字0-9,这样共有62个字符,此外还有两个可打印符号在不同的系统中而不同。


0x01 详细介绍Base64的编码转换方式

下面,详细介绍Base64的编码转换方式。

所谓Base64,就是说选出64个字符作为一个基本字符集。然后,其他所有符号都转换成这个字符集中的字符。

小写字母a-z = 26 
大写字母A-Z = 26
数字0-9 = 10
符号"+"、"/" = 2
# 26+26+10+2 = 64
# 再加上作为垫字的"=",实际上是65个字符

具体来说,转换方式可以分为四步。

第一步,将每三个字节作为一组,一共是24个二进制位。

第二步,将这24个二进制位分为四组,每个组有6个二进制位。

第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节。

第四步,根据下表,得到扩展后的每个字节的对应符号,这就是Base64的编码值。

01.1 Base64转化表

00 A 16 Q 32 g 48 w
01 B 17 R 33 h 49 x
02 C 18 S 34 i 50 y
03 D 19 T 35 j 51 z
04 E 20 U 36 k 52 0
05 F 21 V 37 l 53 1
06 G 22 W 38 m 54 2
07 H 23 X 39 n 55 3
08 I 24 Y 40 o 56 4
09 J 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

因为,Base64将三个字节转化成四个字节,因此Base64编码后的文本,会比原文本大出三分之一左右。


0x02 转换实例

02.1 举一个具体的实例,演示英语单词Man如何转成Base64编码。

  • Man

    M=77=01001101

    a=97=01100001

    n=110=01101110

    • Man=010011010110000101101110=010011010110000101101110=19220546=TWFu
      1. 第一步,"M"、"a"、"n"的ASCII值分别是77、97、110,对应的二进制值是01001101、01100001、01101110,将它们连成一个24位的二进制字符串010011010110000101101110。
      2. 第二步,将这个24位的二进制字符串分成4组,每组6个二进制位:010011、010110、000101、101110。
      3. 第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节:00010011、00010110、00000101、00101110。它们的十进制值分别是19、22、5、46。
      4. 第四步,根据上表,得到每个值对应Base64编码,即T、W、F、u。
    • 因此,Man的Base64编码就是TWFu。

02.2 如果字节数不足三,则这样处理:

  • Ma

    M=77=01001101

    a=97=01100001

    • Ma=0100110101100001=0100110101100001=00010011000101100001
      1. 二个字节的情况:将这二个字节的一共16个二进制位,按照上面的规则,转成三组,最后一组除了前面加两个0以外,后面也要加两个0。这样得到一个三位的Base64编码,再在末尾补上一个"="号。
      2. 比如,"Ma"这个字符串是两个字节,可以转化成三组00010011、00010110、00010000以后,对应Base64值分别为T、W、E,再补上一个"="号,
    • 因此"Ma"的Base64编码就是TWE=。
  • M

    a=97=01100001
    • a=01100001=01100001=0001100000010000
      1. 一个字节的情况:将这一个字节的8个二进制位,按照上面的规则转成二组,最后一组除了前面加二个0以外,后面再加4个0。这样得到一个二位的Base64编码,再在末尾补上两个"="号。
      2. 比如,"M"这个字母是一个字节,可以转化为二组00010011、00010000,对应的Base64值分别为T、Q,再补上两个"="号,
    • 因此"M"的Base64编码就是TQ==。

02.3 中文如何转换

汉字"严"如何转化成Base64编码?

这里需要注意,汉字本身可以有多种编码,比如gb2312、utf-8、gbk等等,每一种编码的Base64对应值都不一样。下面的例子以utf-8为例。

    • utf-8=E4B8A5=11100100 10111000 10100101

      1. 首先,"严"的utf-8编码为E4B8A5,写成二进制就是三字节的"11100100 10111000 10100101"。
      2. 将这个24位的二进制字符串,按照第3节中的规则,转换成四组一共32位的二进制值"00111001 00001011 00100010 00100101",相应的十进制数为57、11、34、37,它们对应的Base64值就为5、L、i、l。
    • 所以,汉字"严"(utf-8编码)的Base64值就是5Lil。