Base64编码中为什么会有等号(=)
如果对字符串"ab"进行Base64编码,得到的结果将是:YWI=,结果中为什么会出现=呢,这就需要了解一下base64编码背后的原理。 
Base64是一种便于网络传输的字节码编码方式,之所以叫Base64是由于它的编码结果是由64个可打印字符组成,这些字符在不同系统间是通用的。 
64个字符如下表所示
	
		
			| 
			 索引 
			 | 
			
			 对应字符 
			 | 
			
			 索引 
			 | 
			
			 对应字符 
			 | 
			
			 索引 
			 | 
			
			 对应字符 
			 | 
			
			 索引 
			 | 
			
			 对应字符 
			 | 
		 
		
			| 
			 0 
			 | 
			
			 A 
			 | 
			
			 17 
			 | 
			
			 R 
			 | 
			
			 34 
			 | 
			
			 i 
			 | 
			
			 51 
			 | 
			
			 z 
			 | 
		 
		
			| 
			 1 
			 | 
			
			 B 
			 | 
			
			 18 
			 | 
			
			 S 
			 | 
			
			 35 
			 | 
			
			 j 
			 | 
			
			 52 
			 | 
			
			 0 
			 | 
		 
		
			| 
			 2 
			 | 
			
			 C 
			 | 
			
			 19 
			 | 
			
			 T 
			 | 
			
			 36 
			 | 
			
			 k 
			 | 
			
			 53 
			 | 
			
			 1 
			 | 
		 
		
			| 
			 3 
			 | 
			
			 D 
			 | 
			
			 20 
			 | 
			
			 U 
			 | 
			
			 37 
			 | 
			
			 l 
			 | 
			
			 54 
			 | 
			
			 2 
			 | 
		 
		
			| 
			 4 
			 | 
			
			 E 
			 | 
			
			 21 
			 | 
			
			 V 
			 | 
			
			 38 
			 | 
			
			 m 
			 | 
			
			 55 
			 | 
			
			 3 
			 | 
		 
		
			| 
			 5 
			 | 
			
			 F 
			 | 
			
			 22 
			 | 
			
			 W 
			 | 
			
			 39 
			 | 
			
			 n 
			 | 
			
			 56 
			 | 
			
			 4 
			 | 
		 
		
			| 
			 6 
			 | 
			
			 G 
			 | 
			
			 23 
			 | 
			
			 X 
			 | 
			
			 40 
			 | 
			
			 o 
			 | 
			
			 57 
			 | 
			
			 5 
			 | 
		 
		
			| 
			 7 
			 | 
			
			 H 
			 | 
			
			 24 
			 | 
			
			 Y 
			 | 
			
			 41 
			 | 
			
			 p 
			 | 
			
			 58 
			 | 
			
			 6 
			 | 
		 
		
			| 
			 8 
			 | 
			
			 I 
			 | 
			
			 25 
			 | 
			
			 Z 
			 | 
			
			 42 
			 | 
			
			 q 
			 | 
			
			 59 
			 | 
			
			 7 
			 | 
		 
		
			| 
			 9 
			 | 
			
			 J 
			 | 
			
			 26 
			 | 
			
			 a 
			 | 
			
			 43 
			 | 
			
			 r 
			 | 
			
			 60 
			 | 
			
			 8 
			 | 
		 
		
			| 
			 10 
			 | 
			
			 K 
			 | 
			
			 27 
			 | 
			
			 b 
			 | 
			
			 44 
			 | 
			
			 s 
			 | 
			
			 61 
			 | 
			
			 9 
			 | 
		 
		
			| 
			 11 
			 | 
			
			 L 
			 | 
			
			 28 
			 | 
			
			 c 
			 | 
			
			 45 
			 | 
			
			 t 
			 | 
			
			 62 
			 | 
			
			 + 
			 | 
		 
		
			| 
			 12 
			 | 
			
			 M 
			 | 
			
			 29 
			 | 
			
			 d 
			 | 
			
			 46 
			 | 
			
			 u 
			 | 
			
			 63 
			 | 
			
			 / 
			 | 
		 
		
			| 
			 13 
			 | 
			
			 N 
			 | 
			
			 30 
			 | 
			
			 e 
			 | 
			
			 47 
			 | 
			
			 v 
			 | 
			  | 
			  | 
		 
		
			| 
			 14 
			 | 
			
			 O 
			 | 
			
			 31 
			 | 
			
			 f 
			 | 
			
			 48 
			 | 
			
			 w 
			 | 
			  | 
			  | 
		 
		
			| 
			 15 
			 | 
			
			 P 
			 | 
			
			 32 
			 | 
			
			 g 
			 | 
			
			 49 
			 | 
			
			 x 
			 | 
			  | 
			  | 
		 
		
			| 
			 16 
			 | 
			
			 Q 
			 | 
			
			 33 
			 | 
			
			 h 
			 | 
			
			 50 
			 | 
			
			 y 
			 | 
			  | 
			  | 
		 
	
 
大家可以看到这里面并没 '=' 这个字符,这是因为 ’=‘ 其实是填充字符。 
如果需要表示上面的64个字符,那么需要6bit,也就是2^6=64,base64的核心思想就是,将3个 
字节拆分成4个6bit,然后对每个6bit的高位补2个0,构成1个字节。也即是每3个字节最终结果将变成4个字节。 
如果原始字符串的字节数不是3的整数倍,那么就用0来填充,用来填充的0就被编码成了'=',这就是出现=的原因,并且只会出现在结果出,如果原始字符刚好是3字节的整数倍,那么就没有等号了。 
回到开头的例子,我们看下ab是如何计算得到YWI=的。 
	- 1、ab对应的ascaii编码的二进制表示为:011000001 01100010
 
	- 2、由于只有两个字节,需要填充到3个字段,也就是:011000001 01100010 00000000
 
	- 3、拆分成四个6bit:011000 010110 001000 000000
 
	- 4、高位补两个0,变成四字节:00011000 00010110 00001000 00000000
 
	- 5、按照上表的对应关系:24-Y 22-W 8-I 填充-=, 也即是YWI=。
 
 
需要注意填充的0是要被转化成=,而不是上表中的A。 
顺便附上golang示例代码
	
		
			| 
			 1 
			2 
			3 
			4 
			5 
			6 
			7 
			8 
			9 
			 | 
			
			 func main() { 
			    str := "ab" 
			    // base64编码 
			    encodedStr := base64.URLEncoding.EncodeToString([]byte(str)) 
			    fmt.Println(encodedStr) // YWI= 
			    // base64解码 
			    decodeStr, _ := base64.URLEncoding.DecodeString(encodedStr) 
			    fmt.Println(string(decodeStr)) // ab 
			} 
			 | 
		 
	
 
如果不希望保留填充的=,可以在编码后去掉,解码前填充上 
示例代码如下: 
	
		
			| 
			 1 
			2 
			3 
			4 
			5 
			6 
			7 
			8 
			9 
			10 
			11 
			12 
			13 
			14 
			15 
			 | 
			
			 func main(){ 
			    str := "ab" 
			    // base64编码 
			    encodedStr := base64.URLEncoding.EncodeToString([]byte(str)) 
			    encodedStr = strings.TrimRight(encodedStr, "=") // 去掉填充的= 
			    fmt.Println(encodedStr) // YWI 
			    // 解码时,长度不是4的倍数,需要用=填充 
			    i := len(encodedStr) % 4 
			    if i != 0 { 
			        encodedStr += strings.Repeat("=", 4-i) 
			    } 
			    // base64解码 
			    decodeStr, _ := base64.URLEncoding.DecodeString(encodedStr) 
			    fmt.Println(string(decodeStr)) // ab 
			 | 
		 
	
 
    |