Javascript 字符串转 Base64 UTF-16BE

Javascript string to Base64 UTF-16BE

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

我无法在 Javascript 中这样做。

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

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

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

AFQAZQBzAHQAZQAgADUAJQAgAOEA4ADBAMAAIADpAOgAyQDIACAA7QDsAM0AzAAgAPMA8gDTANIAIAD6APkA2gDZACAA5wDHACAA4wDDACAAPwAhACwAOw==

我测试了用它发送短信,效果很好。

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

要获取字符串的 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 
const result = btoa(
    new Uint8Array(arr_BE.buffer)
      .reduce((data, byte) => data + String.fromCharCode(byte), '')
  );
console.log( 'same strings:', result === expectedString );
console.log( result );