javascript 使用 Buffer 解析原始字节的 Node.js 数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8058424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 02:07:11  来源:igfitidea点击:

Node.js data parsing raw bytes with Buffer

javascriptparsingnode.js

提问by Greg

I'm trying to use Buffer to parse 29 bytes of data that is formatted in odd ways. I've been using the slice() method to carve up the data on these odd boundaries. A sample stream looks like the following in hex (spaces added for clarity)...

我正在尝试使用 Buffer 来解析以奇怪方式格式化的 29 字节数据。我一直在使用 slice() 方法来分割这些奇怪边界上的数据。示例流在十六进制中如下所示(为清楚起见添加了空格)...

01 1d 00 00 01 0a 0a 0b 0b 0c 0c 00 00 04 d2 00 00 00 0e c8 00 00 00 00 00 00 00 cc c4

01 1d 00 00 01 0a 0a 0b 0b 0c 0c 00 00 04 d2 00 00 00 0e c8 00 00 00 00 00 00 00 cc c4

var raw = '011d0000010a0a0b0b0c0c000004d20000000ec800000000000000ccc4';
buff = new Buffer(raw, 'utf8');
var position = 2;

// message type
var msg_type = buff.slice(position,(position+1)).toString();
position += 1;
console.log('... message type is ' + msg_type);

// event type
var event_type = buff.slice(position,(position+1)).toString();
position += 1;
console.log('... event type is ' + event_type);

// grab more data...

This produces an msg_type=1 and event_type=0. It should be 0 and 1, respectively. All of the slices that follow are wrong.

这会产生 msg_type=1 和 event_type=0。它应该分别为 0 和 1。接下来的所有切片都是错误的。

I'm clearly misunderstanding something with the encoding here. Either during Buffer instantiation or in the toString() extraction.

我显然误解了这里的编码。在 Buffer 实例化期间或在 toString() 提取中。

How can I treat this input stream as a series of hex strings and convert them into binary data that I can operate on?

如何将此输入流视为一系列十六进制字符串并将它们转换为我可以操作的二进制数据?

Thanks!

谢谢!

采纳答案by sarnold

I think the answer is that your Bufferdoesn't represent the object you think it does:

我认为答案是您Buffer不代表您认为的对象:

> var raw = '01 02 03'
> buff = new Buffer(raw, 'utf8')
<Buffer 30 31 20 30 32 20 30 33>
> buff.slice(0,0)
<Buffer >
> buff.slice(0,1)
<Buffer 30>
> buff.slice(0,2)
<Buffer 30 31>
> buff.slice(0,3)
<Buffer 30 31 20>
> buff.slice(0,0).toString()
''
> buff.slice(0,1).toString()
'0'
> buff.slice(0,2).toString()
'01'
> buff.slice(0,3).toString()
'01 '
> buff.slice(0,4).toString()
'01 0'
> buff.slice(0,5).toString()
'01 02'
> buff.slice(0,6).toString()
'01 02 '
> buff.slice(0,7).toString()
'01 02 0'
> buff.slice(0,8).toString()
'01 02 03'
> buff.length
8

Instead of representing a buffer that is three bytes long, this represents a buffer that is 8 bytes long. As you slice into it, you're getting the individual hexadecimal values of the characters. (Note the space is 20-- just like the %20so ubiquitous in URLs.)

这不是表示 3 个字节长的缓冲区,而是表示 8 个字节长的缓冲区。当您切入它时,您将获得字符的各个十六进制值。(注意空格是20——就像%20URL 中无处不在的一样。)

But I have a feeling your var = '01 1d 00...'is just an attempt to populate the buffer with some binary data rather than what's actually happening in your program -- it might be easier to work with a simplified version of how you're actually filling the buffer. Maybe read it out of a file?

但我有一种感觉,您var = '01 1d 00...'只是尝试用一些二进制数据填充缓冲区,而不是程序中实际发生的事情——使用简化版本的实际填充缓冲区可能更容易。也许从文件中读取它?

回答by GraemeF

Node's Buffersupports this directly with the hexencoding:

Node 的Buffer直接支持这种hex编码:

var raw = '011d0000010a0a0b0b0c0c000004d20000000ec800000000000000ccc4';
var buff = new Buffer(raw, 'hex');