如何将uint8数组转换为base64编码的字符串?

时间:2022-10-24 14:25:00

I got a webSocket comunication, I recieve base64 encoded string, convert it to uint8 and work on it, but now I need to send back, I got the uint8 array, and need to convert it to base64 string, so I can send it. How can I make this convertion?

我得到了一个webSocket comunication,我接收base64编码的字符串,将它转换为uint8并处理它,但是现在我需要返回,我得到uint8数组,需要将它转换为base64字符串,所以我可以发送它。我怎样才能做到这一点呢?

6 个解决方案

#1


110  

If your browser has TextDecoder then use that:

如果你的浏览器有TextDecoder,那么请使用:

var u8 = new Uint8Array([65, 66, 67, 68]);
var decoder = new TextDecoder('utf8');
var b64encoded = btoa(decoder.decode(u8));

If you need to support browsers that do not have TextDecoder (currently just IE and Edge), then the best option is to use a TextDecoder polyfill.

如果您需要支持没有TextDecoder(目前只是IE和Edge)的浏览器,那么最好的选择是使用TextDecoder polyfill。

If your strings is plain ASCII and not multibyte Unicode/UTF-8 then there are is a simple alternative using String.fromCharCode that should be fairly universally supported:

如果您的字符串是普通ASCII,而不是多字节Unicode/UTF-8,那么就有一个简单的替代方法,可以使用String.fromCharCode,它应该得到广泛支持:

var u8 = new Uint8Array([65, 66, 67, 68]);
var b64encoded = btoa(String.fromCharCode.apply(null, u8));

And to decode the base64 string back to a Uint8Array:

并将base64字符串解码为Uint8Array:

var u8_2 = new Uint8Array(atob(b64encoded).split("").map(function(c) {
    return c.charCodeAt(0); }));

If you have very large array buffers then the apply may fail and you may need to chunk the buffer (based on the one posted by @RohitSengar). Again, note that this is only correct if your buffer only contains non-multibyte ASCII characters:

如果您有非常大的数组缓冲区,那么应用程序可能会失败,并且您可能需要将缓冲区块(基于@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));

#2


13  

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);
}

You can use this function if you have a very large Uint8Array. This is for Javascript, can be useful in case of FileReader readAsArrayBuffer.

如果你有一个非常大的Uint8Array,你可以使用这个函数。这是用于Javascript的,在FileReader readAsArrayBuffer的情况下是有用的。

#3


8  

Very simple solution and test for JavaScript!

非常简单的解决方案和测试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));

#4


1  

See here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding#Appendix.3A_Decode_a_Base64_string_to_Uint8Array_or_ArrayBuffer

看到https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding Appendix.3A_Decode_a_Base64_string_to_Uint8Array_or_ArrayBuffer

(Decode a Base64 string to Uint8Array or ArrayBuffer with Unicode support)

(使用Unicode支持将Base64字符串解码为Uint8Array或ArrayBuffer)

#5


0  

I'll add another solution that works with non-printable ranges. My guess is this is faster than chaining TextEncoder and btoa.

我将添加另一个使用非可打印范围的解决方案。我的猜测是,这比chaining TextEncoder和btoa要快。

var blob = new Blob( [ uint8ArrayBuffer ], { type: "image/jpeg" } );
var imageUrl = URL.createObjectURL( blob );

This is using HTML5 APIs, and so will not work on Node or other JS based servers, of course. You can see a demo here.

当然,这是在使用HTML5 api,所以不会在Node或其他基于JS的服务器上工作。你可以在这里看到一个演示。

#6


-3  

If all you want is a JS implementation of a base64-encoder, so that you can send data back, you can try the btoa function.

如果您想要的只是一个base64编码器的JS实现,那么您可以将数据发回,您可以尝试btoa函数。

b64enc = btoa(uint);

A couple of quick notes on btoa - it's non-standard, so browsers aren't forced to support it. However, most browsers do. The big ones, at least. atob is the opposite conversion.

在btoa上有一些快速的注释——它是非标准的,所以浏览器不会*支持它。然而,大多数浏览器。至少是大的。atob是相反的转换。

If you need a different implementation, or you find an edge-case where the browser has no idea what you're talking about, searching for a base64 encoder for JS wouldn't be too hard.

如果你需要一个不同的实现,或者你找到一个浏览器不知道你在说什么,搜索一个base64编码器对JS不会太难。

I think there are 3 of them hanging around on my company's website, for some reason...

我想我公司的网站上有3个这样的人,出于某种原因……

#1


110  

If your browser has TextDecoder then use that:

如果你的浏览器有TextDecoder,那么请使用:

var u8 = new Uint8Array([65, 66, 67, 68]);
var decoder = new TextDecoder('utf8');
var b64encoded = btoa(decoder.decode(u8));

If you need to support browsers that do not have TextDecoder (currently just IE and Edge), then the best option is to use a TextDecoder polyfill.

如果您需要支持没有TextDecoder(目前只是IE和Edge)的浏览器,那么最好的选择是使用TextDecoder polyfill。

If your strings is plain ASCII and not multibyte Unicode/UTF-8 then there are is a simple alternative using String.fromCharCode that should be fairly universally supported:

如果您的字符串是普通ASCII,而不是多字节Unicode/UTF-8,那么就有一个简单的替代方法,可以使用String.fromCharCode,它应该得到广泛支持:

var u8 = new Uint8Array([65, 66, 67, 68]);
var b64encoded = btoa(String.fromCharCode.apply(null, u8));

And to decode the base64 string back to a Uint8Array:

并将base64字符串解码为Uint8Array:

var u8_2 = new Uint8Array(atob(b64encoded).split("").map(function(c) {
    return c.charCodeAt(0); }));

If you have very large array buffers then the apply may fail and you may need to chunk the buffer (based on the one posted by @RohitSengar). Again, note that this is only correct if your buffer only contains non-multibyte ASCII characters:

如果您有非常大的数组缓冲区,那么应用程序可能会失败,并且您可能需要将缓冲区块(基于@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));

#2


13  

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);
}

You can use this function if you have a very large Uint8Array. This is for Javascript, can be useful in case of FileReader readAsArrayBuffer.

如果你有一个非常大的Uint8Array,你可以使用这个函数。这是用于Javascript的,在FileReader readAsArrayBuffer的情况下是有用的。

#3


8  

Very simple solution and test for JavaScript!

非常简单的解决方案和测试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));

#4


1  

See here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding#Appendix.3A_Decode_a_Base64_string_to_Uint8Array_or_ArrayBuffer

看到https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding Appendix.3A_Decode_a_Base64_string_to_Uint8Array_or_ArrayBuffer

(Decode a Base64 string to Uint8Array or ArrayBuffer with Unicode support)

(使用Unicode支持将Base64字符串解码为Uint8Array或ArrayBuffer)

#5


0  

I'll add another solution that works with non-printable ranges. My guess is this is faster than chaining TextEncoder and btoa.

我将添加另一个使用非可打印范围的解决方案。我的猜测是,这比chaining TextEncoder和btoa要快。

var blob = new Blob( [ uint8ArrayBuffer ], { type: "image/jpeg" } );
var imageUrl = URL.createObjectURL( blob );

This is using HTML5 APIs, and so will not work on Node or other JS based servers, of course. You can see a demo here.

当然,这是在使用HTML5 api,所以不会在Node或其他基于JS的服务器上工作。你可以在这里看到一个演示。

#6


-3  

If all you want is a JS implementation of a base64-encoder, so that you can send data back, you can try the btoa function.

如果您想要的只是一个base64编码器的JS实现,那么您可以将数据发回,您可以尝试btoa函数。

b64enc = btoa(uint);

A couple of quick notes on btoa - it's non-standard, so browsers aren't forced to support it. However, most browsers do. The big ones, at least. atob is the opposite conversion.

在btoa上有一些快速的注释——它是非标准的,所以浏览器不会*支持它。然而,大多数浏览器。至少是大的。atob是相反的转换。

If you need a different implementation, or you find an edge-case where the browser has no idea what you're talking about, searching for a base64 encoder for JS wouldn't be too hard.

如果你需要一个不同的实现,或者你找到一个浏览器不知道你在说什么,搜索一个base64编码器对JS不会太难。

I think there are 3 of them hanging around on my company's website, for some reason...

我想我公司的网站上有3个这样的人,出于某种原因……