在 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 });
我的 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 });