简介
- 前端在做首屏优化时,常常把小图片转码成BASE64格式
- 浏览器原生提供了btoa(encode to base64) 和atob (decode)的方法
- 这里说一下编码原理,用于理解为什么编码后体积更大
编码原理
- 取字符的ASCII的二进制码,每个字符一个字节8个比特位
如A,对应96,8位二进制为
01100001
代码实现
var table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".split('');
function encode(str) {
if (typeof str !== 'string') {
throw new Error('string type require');
}
var res = [];
str.split('').forEach((i)=>{
var str = i.charCodeAt().toString(2);
while(str.length%8) {
str = '0' + str;
}
res.push( str);
});
var plus = res.length %3;
if (plus ===1) {
res.push('0000');
}
if (plus ===2) {
res.push('00');
}
var s = res.join('').match(/(\d{6})/g).map((item)=>{
var index = parseInt(item, 2);
return table[index]
});
if (plus ===1) {
s.push('==');
}
if (plus ===2) {
s.push('=');
}
return s.join('');
}
function decode (base) {
var plus = 0;
var code = [];
base.split('').forEach((item)=>{
var index = table.indexOf(item);
if (index === 64) {
plus++;
return;
}
str = Number(index).toString(2);
while (str.length%6) {
str = '0' + str;
}
code.push(str);
});
var s= code.join('');
if (plus) {
s=s.slice(0, s.length - 2 * plus);
}
return s.match(/(\d{8})/g).map((item)=>{
return String.fromCharCode(parseInt(item,2));
}).join('');
}
测试
encode('test');// "dGVzdA=="
decode('dGVzdA=='); // "test"
// 原生
btoa('test'); //"dGVzdA=="
atob('dGVzdA=='); //"test"