base64 相信大家都很熟悉了 在浏览器有内置的atob解码和btoa转换 但是其具体是如何实现的呢?
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
base64字符串的每一个字母对应的值是对应字母的下标
比如我这里有一段base64字符串
data:text/plain;base64,aGVsbG8gd29ybGQ=
其中 aGVs
就对应 26 6 21 44
然后 字符串一个字节是8bit base64每四个字节对应原始数据的三个字节
1.原始字节每三个的二进制数据按6位一组分开 分成4个 2.然后左侧补零补成8位 即变成4字节 3.每字节对应编码表对应位置的字符
原始字符串 | ABC |
转换ASCII | 65 66 67 |
对应二进制 | 01000001 01000010 01000011 |
合并 | 010000010100001001000011 |
分割 | 010000 010100 001001 000011 |
补零 | 00010000 00010100 00001001 00000011 |
十进制 | 16 20 9 3 |
对应编码表 | Q U J D |
我们可以验证一下:
1console.log(btoa('ABC')) //QUJD
当然是补零 补充到可以完整分割即可
ps: 如果改变编码表我们也能拥有自己的一套简单加密
来一个按钮 我们点击它 它能下载base64文件
正常来说 href填上base64地址就好了 但这次我们画蛇添足一下 我们先转成文件格式 然后下载 下载是当初期望内容即证明无误
1<a>Download</a>
先初始化对照表
12345 const b64Dic = {};
[].forEach.call(
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
(a, i) => b64Dic[a] = i
);
然后实现base64转原始字节算法
1234567891011121314151617181920212223 function base64ToFile(base64Str) {
const [ext, data] = base64Str.substring(5).split(';base64,');
const raw = new Array(data.length / 4 * 3);
let i = 0;
data.match(/.{4}/g).forEach(c => {
const [v0, v1, v2, v3] = [].map.call(c, a => b64Dic[a])
console.log(v0,v1,v2,v3)
raw[i] = (v0 << 2) + (v1 >> 4);
raw[i + 1] = ((v1 & 0b1111) << 4) + (v2 >> 2)
raw[i + 2] = ((v2 & 0b11) << 6) + v3
i += 3
});
let l = raw.length
while (--l) {
if (raw[l]) {
break
}
}
const bytes = Uint8Array.from(raw.slice(0, l + 1))
const now = Date.now()
return new File([bytes], 'file', {lastModified: now, type: ext});
}
最后生成文件连接 放到下载处
1234 const file = base64ToFile('data:text/plain;base64,aGVsbG8gd29ybGQ=');
const a = document.querySelector('a');
a.download = 'down.txt'
a.href = URL.createObjectURL(file);
newer:
older: