简介
前端在做首屏优化时,常常把小图片转码成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"