UTF-16十六进制解码NodeJS

3

我正在尝试在NodeJS中将UTF-16 Hex(Hello 世界)解码为字符串。我已经尝试通过从十六进制创建缓冲区来进行解码:

let vari = new Buffer.from('00 48 00 65 00 6C 00 6C 00 6F 00 20 4E 16 75 4C', 'hex').toString();

但是当我在 console 中记录 'vari' 时,我并没有得到任何正确的结果。我尝试将 'utf8' 和 'utf16le' 传递给 toString 方法,但这似乎也不起作用。有人能指导我吗?

2个回答

2
由于您正在使用字符串表示的缓冲区创建新缓冲区,因此它无法工作。这将导致一个缓冲区,然后解码时将是缓冲区的字符串'00 48 00 65 00 6C 00 6C 00 6F 00 20 4E 16 75 4C',但由于使用了hex,因此缓冲区将为空。如果您要console.log(Buffer.from('00 48 00 65 00 6C 00 6C 00 6F 00 20 4E 16 75 4C', 'hex'),您将看到一个空缓冲区。
另外,'00 48 00 65 00 6C 00 6C 00 6F 00 20 4E 16 75 4C'不是“Hello 世界”的UTF-16十六进制表示形式。当编码为字符串时,它是这样的:䠀攀氀氀漀 ᙎ䱵。 48 00 65 00 6c 00 6c 00 6f 00 20 00 16 4e 4c 75 是UTF-16十六进制下的“Hello 世界”,我是通过运行console.log(Buffer.from('Hello 世界', 'utf16le'));得到的。
回答如何将'48 00 65 00 6c 00 6c 00 6f 00 20 00 16 4e 4c 75'转换回“Hello 世界”的问题,您可以执行以下操作:
let hexStrings = '48 00 65 00 6c 00 6c 00 6f 00 20 00 16 4e 4c 75'.split(' '); // split string chunks
let hex = hexStrings.map(x => parseInt(x, 16)); // convert string chunks to hexadecimal
let buffer = Buffer.from(hex); // create buffer from hexadecimal array
let string = buffer.toString('utf16le'); // convert buffer to string
console.log(string); // output -> Hello 世界

希望这能有所帮助!

1
我来自node.js最快的将十六进制字符串解码为utf-16的方法

十六进制字符串48 00 65 00 6c 00 6c 00 6f 00 20 00 16 4e 4c 75在utf16le下解码为"Hello 世界"

你有一个十六进制字符串:00 48 00 65 00 6C 00 6C 00 6F 00 20 4E 16 75 4C
让我们来比较一下两个字符串:
48 00 65 00 6c 00 6c 00 6f 00 20 00 16 4e 4c 75 解码为 utf16le 是 'Hello 世界'
00 48 00 65 00 6C 00 6C 00 6F 00 20 4E 16 75 4C 解码为 utf16be 是 'Hello 世界'
唯一的区别是每两个字节被交换了顺序

而且不仅仅是每两个字节,它们的字节顺序也是相反的

你要么手动翻转字节顺序,要么使用函数.toString('utf16be')
be:大端字节序是le:小端字节序的相反

但是node.js不提供buf.toString('utf16be')

要手动“反转字节顺序”,可以使用:buf.swap16()https://nodejs.org/api/buffer.html#buffer_buf_swap16

buf.swap16() 的一个方便用途是在 UTF-16 小端和 UTF-16 大端之间执行快速的原地转换:

const myHexStr = '00 48 00 65 00 6C 00 6C 00 6F 00 20 4E 16 75 4C'
//your bytes shouldn't be whiteSpace separated for `Buffer.from`, it won't work
const removedSpaces = myHexStr.replace(/ /g,'') // '00480065006C006C006F00204E16754C'
const buf = Buffer.from(removedSpaces,'hex') // <Buffer 00 48 00 65 00 6c 00 6c 00 6f 00 20 4e 16 75 4c>
const reversedBuf = buf.swap16() // <Buffer 48 00 65 00 6c 00 6c 00 6f 00 20 00 16 4e 4c 75>
const backToJavascriptString = reversedBuf.toString("utf16le") // 'Hello 世界'

这可以简化为一行代码:
Buffer.from('00 48 00 65 00 6C 00 6C 00 6F 00 20 4E 16 75 4C'.replace(/ /g,''),'hex').swap16().toString("utf16le")

这是一种更好的方法(性能方面):
值得庆幸的是,node.js至少提供了一个函数以大端字节序读取:buf.readUInt16BE()
但它一次只能读取2个字节。你猜还有什么也是2个字节?UTF-16
我的实现:
将所有这些readUInt16BE推送到固定长度的数组中
function ubeFunc(hexx4) {
  const buf = Buffer.from(hexx4, "hex"), len = buf.length/2, arr = new Array(len)
  for (let i = 0; i < len; i++) {
    arr[i]=buf.readUInt16BE(i*2)
  }
  return String.fromCharCode(...arr)
}

如何使用它。
ubeFunc('00 48 00 65 00 6C 00 6C 00 6F 00 20 4E 16 75 4C'.replace(/ /g,'')) // 'Hello 世界'

这是最快的方法:在这里阅读:node.js将十六进制字符串解码为utf-16的最快方法


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接