MDN中给出了base64编码函数btoa和解码函数atob.let encoded = btoa('yo'); // "eW8="let decoded = atob(encoded); // 'yo'
Unicode问题解法
有个小坑是它只支持ASCII. 如果你调用btoa("中文")会报错:Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
浏览器中DOMString是UTF-16编码. 如果输入字符串中包含超过8位(0x00~0xFF)的字符, 就会报这个错误.
思路一
对整个字符串进行转义(如使用encodeURIComponent 进行UTF-8转义)然后再btoa编码.let Base64 = {
encode(str) { // first we use encodeURIComponent to get percent-encoded UTF-8,
// then we convert the percent encodings into raw bytes which
// can be fed into btoa.
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function toSolidBytes(match, p1) { return String.fromCharCode('0x' + p1);
}));
},
decode(str) { // Going backwards: from bytestream, to percent-encoding, to original string.
return decodeURIComponent(atob(str).split('').map(function (c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
}
};let encoded = Base64.encode("哈ha"); // "5ZOIaGE="let decoded = Base64.decode(encoded); // "哈ha"
思路二
将UTF-16的DOMString转化成UTF-8的字节数组然后编码.
MDN上此思路的解法用了很多库, 就不推荐了.
网上找到了下面这段代码, 思路是一样的, 但是是直接裸写的转换代码./**
*
* Base64 encode / decode
* http://www.webtoolkit.info
*
**/var Base64 = { // private property
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
// public method for encoding
, encode: function (input) { var output = ""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0;
input = Base64._utf8_encode(input); while (i
{
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) <> 4);
enc3 = ((chr2 & 15) <> 6);
enc4 = chr3 & 63; if (isNaN(chr2))
{
enc3 = enc4 = 64;
} else if (isNaN(chr3))
{
enc4 = 64;
}
output = output + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
} // Whend
return output;
} // End Function encode
// public method for decoding
,decode: function (input) { var output = ""; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); while (i
{
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 <> 4);
chr2 = ((enc2 & 15) <> 2);
chr3 = ((enc3 & 3) <
output = output + String.fromCharCode(chr1); if (enc3 != 64)
{
output = output + String.fromCharCode(chr2);
} if (enc4 != 64)
{
output = output + String.fromCharCode(chr3);
}
} // Whend
output = Base64._utf8_decode(output); return output;
} // End Function decode
// private method for UTF-8 encoding
,_utf8_encode: function (string) { var utftext = "";
string = string.replace(/\r\n/g, "\n"); for (var n = 0; n
{ var c = string.charCodeAt(n); if (c
{
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c
{
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else
{
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
} // Next n
return utftext;
} // End Function _utf8_encode
// private method for UTF-8 decoding
,_utf8_decode: function (utftext) { var string = ""; var i = 0; var c, c1, c2, c3;
c = c1 = c2 = 0; while (i
{
c = utftext.charCodeAt(i); if (c
{
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c
{
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) <
i += 2;
} else
{
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) <
i += 3;
}
} // Whend
return string;
} // End Function _utf8_decode }
参考
作者:柳正来
链接:https://www.jianshu.com/p/82afa633033e