1

我正在尝试将字符串转换为 BASE64 和 utf-16 Big Endian 字符集,以便使用 sms API 发送它。

我无法在 Javascript 中这样做。

这是我想在短信中发送的原始 js 字符串:

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

使用btoa(originalString)我得到VGVzdGUgNSUyNSDh4MHAIOnoycgg7ezNzCDz8tPSIPr52tkg58cg48MgPyEsOw==的不是我需要的......我为此目的使用了一个在线转换器,这是正确的值:

AFQAZQBzAHQAZQAgADUAJQAgAOEA4ADBAMAAIADpAOgAyQDIACAA7QDsAM0AzAAgAPMA8gDTANIAIAD6APkA2gDZACAA5wDHACAA4wDDACAAPwAhACwAOw==

我测试了用它发送短信,它工作正常。

4

2 回答 2

3

要获取字符串的 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 );

于 2020-05-08T15:12:27.297 回答
2

这并不容易,因为编码 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

另外,这里是对 UTF16BE 的 base64 编码的一个很好的解释:https ://crawshaw.io/blog/utf7

于 2020-05-08T14:30:37.887 回答