我有一个 webSocket 通信,我收到 base64 编码的字符串,将其转换为 uint8 并对其进行处理,但现在我需要发回,我得到了 uint8 数组,并且需要将其转换为 base64 字符串,以便我可以发送它。我怎样才能进行这种转换?
如何将 uint8 数组转换为 base64 编码字符串?
IT技术
javascript
arrays
base64
2021-02-10 13:14:49
6个回答
如果您的数据可能包含多字节序列(不是纯 ASCII 序列)并且您的浏览器具有TextDecoder,那么您应该使用它来解码您的数据(为 TextDecoder 指定所需的编码):
var u8 = new Uint8Array([65, 66, 67, 68]);
var decoder = new TextDecoder('utf8');
var b64encoded = btoa(decoder.decode(u8));
如果您需要支持没有 TextDecoder 的浏览器(目前只有 IE 和 Edge),那么最好的选择是使用TextDecoder polyfill。
如果您的数据包含纯 ASCII(不是多字节 Unicode/UTF-8),那么有一个简单的替代方法String.fromCharCode
应该得到普遍支持:
var ascii = new Uint8Array([65, 66, 67, 68]);
var b64encoded = btoa(String.fromCharCode.apply(null, ascii));
并将 base64 字符串解码回 Uint8Array:
var u8_2 = new Uint8Array(atob(b64encoded).split("").map(function(c) {
return c.charCodeAt(0); }));
如果您有非常大的数组缓冲区,那么应用可能会失败,您可能需要对缓冲区进行分块(基于@RohitSengar 发布的那个)。同样,请注意,这仅在您的缓冲区仅包含非多字节 ASCII 字符时才正确:
function Uint8ToString(u8a){
var CHUNK_SZ = 0x8000;
var c = [];
for (var i=0; i < u8a.length; i+=CHUNK_SZ) {
c.push(String.fromCharCode.apply(null, u8a.subarray(i, i+CHUNK_SZ)));
}
return c.join("");
}
// Usage
var u8 = new Uint8Array([65, 66, 67, 68]);
var b64encoded = btoa(Uint8ToString(u8));
如果您使用的是 Node.js,那么您可以使用此代码将 Uint8Array 转换为 base64
var b64 = Buffer.from(u8).toString('base64');
非常简单的 JavaScript 解决方案和测试!
ToBase64 = function (u8) {
return btoa(String.fromCharCode.apply(null, u8));
}
FromBase64 = function (str) {
return atob(str).split('').map(function (c) { return c.charCodeAt(0); });
}
var u8 = new Uint8Array(256);
for (var i = 0; i < 256; i++)
u8[i] = i;
var b64 = ToBase64(u8);
console.debug(b64);
console.debug(FromBase64(b64));
所有已经提出的解决方案都有严重的问题。一些解决方案无法在大型数组上工作,一些提供错误的输出,如果中间字符串包含多字节字符,一些会在 btoa 调用时抛出错误,一些会消耗比需要更多的内存。
所以我实现了一个直接转换功能,无论输入如何,它都可以工作。它在我的机器上每秒转换大约 500 万字节。
https://gist.github.com/enepomnyaschih/72c423f727d395eeaa09697058238727
function Uint8ToBase64(u8Arr){
var CHUNK_SIZE = 0x8000; //arbitrary number
var index = 0;
var length = u8Arr.length;
var result = '';
var slice;
while (index < length) {
slice = u8Arr.subarray(index, Math.min(index + CHUNK_SIZE, length));
result += String.fromCharCode.apply(null, slice);
index += CHUNK_SIZE;
}
return btoa(result);
}
如果您有一个非常大的 Uint8Array,则可以使用此函数。这是针对 Javascript 的,在 FileReader readAsArrayBuffer 的情况下很有用。
其它你可能感兴趣的问题