我使用这个问题的公认答案在通过 ASCII-cookie [atob, btoa are base64[with +/]<->js binary string] 传输的 base64Url 数据领域中创建 base64Url string <-> arrayBuffer 转换,所以我决定发布代码。
我们中的许多人可能想要转换,并且客户端-服务器通信可能使用 base64Url 版本(尽管如果我理解得很好,cookie 可能包含 +/ 和 -_ 字符,只有 ",;\ 字符和 128 ASCII 中的一些邪恶字符是不允许的)。但是 url 不能包含 / 字符,因此更广泛地使用 b64 url 版本,这当然不是 atob-btoa 支持的......
看到其他评论,我想强调一下,我的用例是通过 url/cookie 传输 base64Url 数据,并尝试将此加密数据与 js crypto api (2017) 一起使用,因此需要 ArrayBuffer 表示和 b64u <-> arrBuff 转换...如果数组缓冲区表示 base64(ascii 的一部分)以外的内容,则此转换将不起作用,因为 atob,btoa 仅限于 ascii(128)。查看合适的转换器,如下所示:
buff -> b64u 版本来自 Mathias Bynens 的推文,(也)感谢那个!他还写了一个base64编码器/解码器:
https ://github.com/mathiasbynens/base64
来自 java,在尝试理解 java byte[] 实际上是 js Int8Array (signed int) 的代码时可能会有所帮助,但我们在这里使用无符号版本 Uint8Array,因为 js 转换适用于它们。它们都是256位的,所以我们现在在js中称之为byte[]...
代码来自模块类,这就是为什么是静态的。
//utility
/**
* Array buffer to base64Url string
* - arrBuff->byte[]->biStr->b64->b64u
* @param arrayBuffer
* @returns {string}
* @private
*/
static _arrayBufferToBase64Url(arrayBuffer) {
console.log('base64Url from array buffer:', arrayBuffer);
let base64Url = window.btoa(String.fromCodePoint(...new Uint8Array(arrayBuffer)));
base64Url = base64Url.replaceAll('+', '-');
base64Url = base64Url.replaceAll('/', '_');
console.log('base64Url:', base64Url);
return base64Url;
}
/**
* Base64Url string to array buffer
* - b64u->b64->biStr->byte[]->arrBuff
* @param base64Url
* @returns {ArrayBufferLike}
* @private
*/
static _base64UrlToArrayBuffer(base64Url) {
console.log('array buffer from base64Url:', base64Url);
let base64 = base64Url.replaceAll('-', '+');
base64 = base64.replaceAll('_', '/');
const binaryString = window.atob(base64);
const length = binaryString.length;
const bytes = new Uint8Array(length);
for (let i = 0; i < length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
console.log('array buffer:', bytes.buffer);
return bytes.buffer;
}