在 Javascript 中转换 16 位 Unicode 十六进制字符串

Convert 16-bit Unicode hex string in Javascript

我的 websocket 应用从其他仅使用 16 位 Unicode (wchar_t) 字符串的来源获取字符串输入。在发送之前,字符串被编码为十六进制,此处显示单词 'HELLO' 的示例:

680065006C006C006F00

如何将该十六进制字符串转换为有效的 Javascript 字符串?我找到的最接近的是此处的 Node.js 示例 (UTF-16 Hex Decode NodeJS),但我没有使用 Node.js,所以它不起作用。

如果所有的字符串都是英文的,那么跳过每个“00”十六进制数字就很容易了,但是同样,我需要支持所有语言,我不确定如何从两个字节构造一个字符.

谢谢@samthecodingman。 fromCodePoint 正是我要找的。还需要交换字节顺序,但这似乎可行。

for (var i = 0; i < strLen; i+=4) {
    c = parseInt(str.substr(i+2,2) + str.substr(i,2), 16)
    s = s + String.fromCodePoint(c);
}

由于 String.prototype.substr() 是一种非标准方法,您应该避免使用它,如下例所示:

const str = "680065006C006C006F00", strLen = str.length;
let decoded = "";
for (const i = 0; i < strLen; i+=4) {
    let c = parseInt(str[i+2] + str[i+3] + str[i] + str[i+1], 16)
    decoded += String.fromCodePoint(c);
}

虽然我会定义一些函数来处理它:

const decodeUTF16BytePair = (p) => String.fromCodePoint(parseInt(p[2]+p[3]+p[0]+p[1], 16));

const decodeUTF16ByteString = (str) => {
  let decoded = "", strLen = str.length;
  if (strLen % 4 != 0) {
    throw new Error("Unexpected byte string length");
  }
  for (let i = 0; i < strLen; i+=4) {
    decoded += decodeUTF16BytePair(str.slice(i, i+4));
  }
  return decoded;
}

因为String.fromCodePoint()可以将它的参数强制转换为一个数字,我们也可以使用:

const decodeUTF16ByteString = (str) => {
  let decoded = "", strLen = str.length;
  if (strLen % 4 != 0) {
    throw new Error("Unexpected byte string length");
  }
  for (let i = 0; i < strLen; i+=4) {
    decoded += String.fromCodePoint("0x"+str[i+2]+str[i+3]+str[i]+str[i+1]);
  }
  return decoded;
}

重要的是,使用上述方法,您将切换输入字节的字节顺序,但某些平台可能不需要这种反转。

实例

const decodeUTF16ByteString = (str) => {
  let decoded = "", strLen = str.length;
  if (strLen % 4 != 0) {
    throw new Error("Unexpected byte string length");
  }
  for (let i = 0; i < strLen; i+=4) {
    decoded += String.fromCodePoint("0x"+str[i+2]+str[i+3]+str[i]+str[i+1]);
  }
  return decoded;
}

const input = "680065006C006C006F00";
const output = decodeUTF16ByteString(input)
  
console.log({ input, output });