BASE64是网络上最常见的用于传输8Bit字节代码的编码方式之一,例如可以将小图片直接编码为BASE64格式直接通过接口传输。
在RFC2045中是这样定义的,BASE64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。
BASE64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6= 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。
例如:
转换前 aaaaaabb ccccdddd eeffffff (a,b,c,d,e,f代表0/1)
转换后 00aaaaaa 00bbcccc 00ddddee 00ffffff
上面的三个字节是原文,下面的四个字节是转换后的Base64编码,其前两位均为0。转换后,用一个码表来得到目的字符串(也就是最终的BASE64编码)
编码表(RFC2045)
VALUE | ENCODING | VALUE | ENCODING | VALUE | ENCODING | VALUE | ENCODING |
0 | A | 16 | Q | 32 | g | 48 | w |
1 | B | 17 | R | 33 | h | 49 | x |
2 | C | 18 | S | 34 | i | 50 | y |
3 | D | 19 | T | 35 | j | 51 | z |
4 | E | 20 | U | 36 | k | 52 | 0 |
5 | F | 21 | V | 37 | l | 53 | 1 |
6 | G | 22 | W | 38 | m | 54 | 2 |
7 | H | 23 | X | 39 | n | 55 | 3 |
8 | I | 24 | Y | 40 | o | 56 | 4 |
9 | 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 | / |
再举一例:
转换前 1010110110111010 01110110
转换后 0010101100011011 00101001 00110110
十进制 43 27 4154
对应码表中的值 r b p2
所以上面的24位编码,编码后的BASE64值为 rbp2。解码同理,把 rbq2 的二进制位连接上再重组得到三个8位值,得出原码。
但是原文的字节数量不一定是3的倍数。解决办法是这样的:原文的字节不够的地方可以用全0来补足,转换时BASE64编码用=号来代替。这就是为什么有些BASE64编码会以一个或两个等号结束的原因,但等号最多只有两个。因为:
所以余数任何情况下都只可能是0,1,2这三个数中的一个。如果余数是0,就表示原文字节数正好是3的倍数。如果是1,为了让BASE64编码是4的倍数,就要补2个等号;同理,如果是2,就要补1个等号。