Javascript Base64 atob 与 btoa 方法之 a b 探究

Javascript 实现 Base64 编码和解码

var cod = {
    ut8: {
        enc: TextEncoder.prototype.encode.bind(new TextEncoder()),
        dec: TextDecoder.prototype.decode.bind(new TextDecoder()),
    },
    b64: {
        enc: str => btoa(String.fromCodePoint(...cod.ut8.enc(str))),
        dec: a64 => cod.ut8.dec(Uint8Array.from(atob(a64), c=>c.codePointAt(0))),
    },
};

// use it for base64 encode/decode
var {enc, dec} = cod.b64;
console.log(enc("汉字china"));		// "5rGJ5a2XY2hpbmE="
console.log(dec(enc("汉字china")));	// "汉字china"

atob 与 btoa 的 a b 探究

  • 要弄清这个问题,最好结合mdn原文,进行读解:
    mdn原文:https://developer.mozilla.org/en-US/docs/Glossary/Base64
  • 注意其中的"NOTE"部分:
    Base64 is a binary encoding rather than a text encoding,
    Base64是 二进制编码 而不是 文本编码

    Base64

    二进制编码
    ?! …
    懵了吧!
  • 别急,继续看:
    “atob” should be read as “ASCII to binary”
    “atob”应读作“ASCII转二进制”
    “btoa” should be read as “binary to ASCII”
    “btoa”应读作“二进制转ASCII”
  • 还是懵吧!
    原文意思是:
    这里的"b",不是代表"Base64",而是"Binary",
    而代表"Base64"编码的,反而是这里的"a",即:
    a= “5rGJ5a2XY2hpbmE=
    体会到反直觉了么?
  • 继续:
    the two functions use strings to represent binary data,
    这两个函数使用字符串来 表示 二进制数据,
  • 这就有点意思了,继续:
    the code point of each character representing the value of each byte.
    每个字符的 代码点 表示每个字节的值。
  • get 到关键点了, “code point” 就是这个关键点
    试试以下代码:
// 为条理清晰,使用我上篇文章的Promise知识点写出base64的编解码代码
Promise.resolve("汉字china")
	// string 按utf8编码方式转 bytes(uint8arr)
	.then( TextEncoder.prototype.encode.bind(new TextEncoder()) )
	// bytes 查表转 bytesASCII,这个 bytesASCII 就是上面讨论的"b"
	.then( bytes => String.fromCodePoint(...bytes) )	//"bytesASCII"="中国china"
	// btoa ---> bytesASCII 转 ASCII64(base64)
	.then( btoa )
	.then( ascii64 => console.log(ascii64) || ascii64 )
	.then( atob )
	.then( bytesASCII => Uint8Array.from(bytesASCII, char => char.codePointAt(0)) )
	.then( TextDecoder.prototype.decode.bind(new TextDecoder()) )
	.then( string => console.log(string) || string )
;

其实 “a” 中的ASCII码,只用了其中 64个可见字符,即基于64个字符的编码方式,这也是Base64名称的由来。

  • Base64 与 String 互转解析:
    1、“a”:特定的64个可见ASCII码符,干脆叫 “ASCII64” 码符,好对应 “a”
    2、“b”:0~255的ASCII码符,与 “bytes” 数值一一对应,别名 “bytesASCII”,好对应 “b”
    3、“atob”:ASCII64 to bytesASCII
    4、“btoa”:bytesASCII to ASCII64
    5、“Uint8Array”:干脆叫 “bytes”
    6、查表互转"bytes" 和 “bytesASCII”:
    “String.fromCodePoint”:用数值查出对应字符
    “char.codePointAt(0)”:用字符查出对应数值,单个进行
    7、String/Base64互转:string <=> bytes <=> bytesASCII <=> ASCII64

把 Base64 当成 Ascii64 理解 你就不会混淆 atob 和 btoa 了

附上上段代码的完整带参版,思路更清晰些:

Promise.resolve("汉字china")
	.then( string => TextEncoder.prototype.encode.bind(new TextEncoder())( string) )
	.then( bytes => String.fromCodePoint(...bytes) )
	.then( bytesASCII => btoa( bytesASCII) )
	.then( ascii64 => console.log( '编码结果:',ascii64) || ascii64 )
	.then( ascii64 => atob( ascii64) )
	.then( bytesASCII => Uint8Array.from( bytesASCII, char => char.codePointAt(0)) )
	.then( bytes => TextDecoder.prototype.decode.bind(new TextDecoder())( bytes) )
	.then( string => console.log( '解码结果:',string) || string )
;
  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_1105048351

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值