网络信息传递时,一些二进制资源往往需要转换为Base64编码进行传输,以提高传输效率,例如webpack提供了将图片格式文件转换为Base64格式,下面将简单介绍Base64编码的原理和实现过程

Base64编码原理

Base64是一种基于64个可打印字符来表示二进制数据的表示方法。base64要求将每三个8bits字节转换为四个6bit的字节(3 * 8 = 4 * 6 = 24),然后将转换后的6bit往高位添加2个0,组成4个8bit的字节,再根据这4个8bit字节的十进制在索引表中查找对应的值,此时得到的结果就是Base64值。

因此,理论上,转换后的字符串的长度要比原来的字符串长度长1/3,例如:转换前的4*6二进制字符串为:aaaaaa bbbbbb cccccc dddddd,在每个字节高位添加两个零后就是: 00aaaaaa 00bbbbbb 00cccccc 00dddddd,此时长度就比原字符串长度多了1/3。

一下是一段话编码为Base64前后的变化:

编码前:

Man is distinguished, not only by his reason, but by this singular passion from
other animals, which is a lust of the mind, that by a perseverance of delight
in the continued and indefatigable generation of knowledge, exceeds the short
vehemence of any carnal pleasure.

编码后:

TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=

前面提到了Base64算法的索引表,Base64的索引表由64个ASCII字符组成:0-9,26个英文小写字母a-z,26个英文大写字母:A-Z,除此之外还有额外两个字符”+”和”/”。

理论上上面的索引表还要加入padding:”=”,前面提到一个字符串转成Base64时是生成4个字符,如果待转换的字符串转换后不足4个Base64字符,则空白的地方需要使用“=”补充,看下面的例子就能明白:

这里进行一个小结,普通字符串文本转换为Base64的基本过程为:

字符串对应的字符转换为ASCII→将该ASCII转换为8位二进制→将转换的8位二进制进行6bit拆分,高位填充0,形成新的二进制→根据新的二进制从Base64索引表查找结果

Base64编码的实现

了解了Base64的转换规则后,我们通过JavaScript来简单实现Base的编码以及解码:

 1 var Base64 = {
 2  
 3 _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
 4  
 5 //将字符串转换为Base64
 6 encode: function(input) {
 7     var output = "";
 8     var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
 9     var i = 0;
10  
11     while (i < input.length) {
12  
13         chr1 = input.charCodeAt(i++);
14         chr2 = input.charCodeAt(i++);
15         chr3 = input.charCodeAt(i++);
16  
17         enc1 = chr1 >> 2;
18         enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
19         enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
20         enc4 = chr3 & 63;
21  
22         if (isNaN(chr2)) {
23             enc3 = enc4 = 64;
24         } else if (isNaN(chr3)) {
25             enc4 = 64;
26         }
27         output = output + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
28     }
29     return output;
30 },
31  
32 //将Base64解码为可读字符串
33 decode: function(input) {
34     var output = "";
35     var chr1, chr2, chr3;
36     var enc1, enc2, enc3, enc4;
37     var i = 0;
38  
39     input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
40  
41     while (i < input.length) {
42         enc1 = this._keyStr.indexOf(input.charAt(i++));
43         enc2 = this._keyStr.indexOf(input.charAt(i++));
44         enc3 = this._keyStr.indexOf(input.charAt(i++));
45         enc4 = this._keyStr.indexOf(input.charAt(i++));
46  
47         chr1 = (enc1 << 2) | (enc2 >> 4);
48         chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
49         chr3 = ((enc3 & 3) << 6) | enc4;
50  
51         output = output + String.fromCharCode(chr1);
52  
53         if (enc3 != 64) {
54             output = output + String.fromCharCode(chr2);
55         }
56         if (enc4 != 64) {
57             output = output + String.fromCharCode(chr3);
58         }
59     }
60     return output;
61     }
62 }
View Code

相关文章:

  • 2021-09-12
  • 2022-03-06
  • 2022-01-10
  • 2022-01-15
  • 2022-02-13
  • 2021-10-21
猜你喜欢
  • 2022-12-23
  • 2021-06-19
  • 2021-08-09
  • 2021-12-12
  • 2022-02-07
  • 2022-01-22
相关资源
相似解决方案