Как получить строку в кодировке UTF8 из строки в кодировке Base64 в Javascript?

#javascript #node.js #utf-8 #base64 #utf-16

Вопрос:

AEEAQgBDAGEAYgBj является Base64 для ABCabc однако, когда я запускаю этот код:

 let a = Buffer.from('AEEAQgBDAGEAYgBj', 'base64').toString('utf-8');
console.log(Buffer.from(a, 'utf8'));
 

напечатанный результат в консоли <Buffer 00 41 00 42 00 43 00 61 00 62 00 63> имеет значение UTF16 (ФАЙЛ).

Я бы предположил, что, поскольку я создаю буфер из строки в кодировке UTF8, результатом будет <Buffer 41 42 43 61 62 63> . Итак, как я могу получить фактическую строку в кодировке UTF8 из Base64?

Ответ №1:

Проблема в том, что ваши исходные данные закодированы в кодировке Base64 UTF16-BE. Если вы посмотрите a после первой строки, вы увидите, что в ней есть те нулевые байты, которые вы видите в последнем буфере:

 let a = Buffer.from("AEEAQgBDAGEAYgBj", "base64").toString("utf-8");
console.log(a.length);
// 12
console.log([...a].map(ch => ch.charCodeAt(0).toString(16).padStart(2, "0")).join(" "));
// 00 41 00 42 00 43 00 61 00 62 00 63
 

Таким образом, возникает вопрос: как прочитать текст UTF16-BE, который у вас есть в буфере Buffer.from("AEEAQgBDAGEAYgBj", "base64") . Node.js’s Buffer не поддерживает UTF16-BE напрямую ( "utf16be" в его стандартной библиотеке нет кодировки), но вы можете попасть туда через swap16 , а затем прочитать буфер как UTF16-LE ( "utf16le" , который находится в Node.js стандартная библиотека):

 let a = Buffer.from("AEEAQgBDAGEAYgBj", "base64").swap16().toString("utf16le");
console.log(a.length);
// 6
console.log(a);
// ABCabc
 

Теперь a это обычная строка. Если вам нужен буфер, содержащий его содержимое в формате UTF8, вы можете использовать Buffer.from(a).toString("utf8") :

 let a = Buffer.from("AEEAQgBDAGEAYgBj", "base64").swap16().toString("utf16le");
console.log(a.length);
// 6
console.log(a);
// ABCabc
let b = Buffer.from(a); // (Default is `"utf8"` but you could supply that explicitly)
console.log(b);
// <Buffer 41 42 43 61 62 63>