Javascript строка в Base64 UTF-16BE - PullRequest
1 голос
/ 08 мая 2020

Я пытаюсь преобразовать строку в BASE64 и кодировку utf-16 Big Endian, чтобы отправить ее с помощью sms API.

Я не могу сделать это в Javascript.

Это исходная js строка, которую я хочу отправить в sms:

const originalString = 'Teste 5% áàÁÀ éèÉÈ íìÍÌ óòÓÒ úùÚÙ çÇ ãà ?!,;';

Используя btoa(originalString), я получаю VGVzdGUgNSUyNSDh4MHAIOnoycgg7ezNzCDz8tPSIPr52tkg58cg48MgPyEsOw==, это не то, что мне нужно ... Я использовал для этой цели онлайн-конвертер, и это правильное значение:

AFQAZQBzAHQAZQAgADUAJQAgAOEA4ADBAMAAIADpAOgAyQDIACAA7QDsAM0AzAAgAPMA8gDTANIAIAD6APkA2gDZACAA5wDHACAA4wDDACAAPwAhACwAOw==

Я тестировал отправку sms с ним и работает нормально.

Ответы [ 2 ]

2 голосов
/ 08 мая 2020

Чтобы получить версию строки UTF-16, нам нужно сопоставить все ее символы с их значением charCodeAt(0).
Отсюда мы можем построить Uint16Array который будет содержать текстовый файл UTF-16LE.
Нам просто нужно поменять местами все элементы в этом Uint16Array , чтобы получить версию UTF-16BE.

Тогда это просто вопрос чтобы закодировать это в base64.

const originalString = 'Teste 5% áàÁÀ éèÉÈ íìÍÌ óòÓÒ úùÚÙ çÇ ãà ?!,;';
const expectedString = "AFQAZQBzAHQAZQAgADUAJQAgAOEA4ADBAMAAIADpAOgAyQDIACAA7QDsAM0AzAAgAPMA8gDTANIAIAD6APkA2gDZACAA5wDHACAA4wDDACAAPwAhACwAOw==";

const codePoints = originalString.split('').map( char => char.charCodeAt(0) );
const swapped = codePoints.map( val => (val>>8) | (val<<8) );
const arr_BE = new Uint16Array( swapped );

// ArrayBuffer to base64 borrowed from https://stackoverflow.com/a/42334410/3702797
const result = btoa(
    new Uint8Array(arr_BE.buffer)
      .reduce((data, byte) => data + String.fromCharCode(byte), '')
  );
console.log( 'same strings:', result === expectedString );
console.log( result );
1 голос
/ 08 мая 2020

Это непросто, поскольку кодировка UTF16BE практически не поддерживается в javascript.

Задача состоит в преобразовании строки в буфер байтов; как только вы поместите его в буфер, преобразовать его в base64 очень просто. Один из способов сделать это - использовать библиотеку для добавления поддержки UTF16BE, например iconv-lite.

Вот пример, который вы можете запустить в узле:

const iconv = require('iconv-lite');
const originalString = 'Teste 5% áàÁÀ éèÉÈ íìÍÌ óòÓÒ úùÚÙ çÇ ãà ?!,;';
const buffer = iconv.encode(originalString, 'utf16be');
console.log(buffer.toString('base64'));

Вы можете видеть его демонстрация здесь: https://repl.it/@RobBrander / SelfishForkedAlphatest

Кроме того, вот отличное объяснение кодировки base64 UTF16BE: https://crawshaw.io/blog/utf7

...