Base64 是用64个可打印的字符来描述数据的编码方式
为什么要整这个Base64呢,那是因为有的时候我们需要以可打印的字符串的形式传递数据,比如url传递之类的
假设有个4字节的数据 [97, 32, 245, 0],我们要把它转成可打印的字符串的形式,首先不能直接把它转成字符串,因为ASCII中有不可打印的字符,且会出现乱码
当然我们可以以json的形式 [97, 32, 245, 0],也能以十六进制的形式 6120F500,但是这样感觉太冗余了,有没有更好的办法呢
这个时候就能用到Base64了,它有64个可打印字符,它能描述最大2的6次方的数值,描述3个字节的数据只需要用到3*8/6=4个字符
Base64编码的核心逻辑就是把原来的字节数组每3个字节中的24位分成4份,每份6位用其字符集的中字符来描述
比如 [97, 32, 245, 0],它的二进制位是这样的
01100001 00100000 11110101 00000000
Base64是按3个字节为一组处理的,所以先看前3个字节
01100001 00100000 11110101
把这3个字节分成4份,每份6位
011000 010010 000011 110101
每份按照一个字节转成具体的数值,根据数值对应字符(因为只有6位,所以要前头补两个0位凑够8位一个字节,本质上还是在2的6次方范围内)
格式:二进制位(Base64值,Base64字符)
00011000(24,Y) 00010010(18,S) 00000011(3,D) 00110101(53,1)
把字符拼起来得到 YSD1(区分大小写)
然后来看最后一个字节 00000000 ,因为一个字节8位,不是6的倍数,没发处理,而24正好是8和6的倍数,因此要凑够3字节24位,需要补2个字节
最后一个字节在补2个字节
00000000 00000000 00000000
分成4份
000000 000000 000000 000000
补0然后查表
00000000(0,A) 00000000(0,A) 00000000(=) 00000000(=)
因为补了2个字节,且要和值为0(符号A)的非补字节区分开来,特规定通过补充产生的字节用=代替,补几个字节加几个=
拼接得到字符串AA==
最终得到Base64字符串YSD1AA==,一共8个字符,比json的少,和十六进制的一样(这是最糟糕的情况,因为补了2个字节,相当于描述了6个字节,理想情况下如果字节数正好是3的倍数,则比十六进制每3个字节要少2个字符)
上面讲的是纯字节数组转Base64字符串进行数据传输的情况
很多时候我们是要把字符串进行Base64编码,就拿ASCII字符串来说,3个字节只需要3个字符,但是Base64却要4个字符,再加上有可能的补字节机制,导致对字符串Base64编码后得到的base64字符串要比原字符串大