使用 Node.js 进行条件二进制解包

Posted

技术标签:

【中文标题】使用 Node.js 进行条件二进制解包【英文标题】:Conditional Binary Unpacking With Node.js 【发布时间】:2014-02-03 18:43:30 【问题描述】:

我的任务是创建一个 node.js 程序,该程序具有三个主要组件:侦听传入数据(以打包二进制形式出现),解压缩并解析该数据,然后将其发布到 postgreSQL 数据库。我遇到的问题是,当前提供的所有 npm 库节点都不能很好地处理解包的条件格式。

数据采用一般格式:

    标头。这部分在每个传入的数据包上固定为 20 个字节,因此易于解析。

    第一个信息部分。这具有可变长度。

    第二个信息部分。这具有可变长度。

    第三个信息部分。这具有可变长度。

幸运的是,在每种情况下,我都将每个部分的长度作为前两个字节。

我有一个指南告诉我每个信息包将在标头中保留多长时间使用bufferpack 和binary npm 库来解析数据。对于第一个信息包,我没有一个固定的指南是幸运的:

var binary = require('binary');
var bufferpack = require('bufferpack');
//The data is received as a buffer in the main program.
exports.execute = function (data) 
    //The first piece of information is 8 bytes thus requiring
    //using binary npm. It is also big endian unsigned.
    //Bytes 0 - 7:
    var info1 = binary.parse(data).word64bu('data1').vars;
    //The next info packet is 1 unsigned byte. 
    var info2 = bufferpack.unpack('B', data, 8);
    //The next info packet is 9 bytes long, but is not collected 
    //because it is not required.

    //The last packet then is 2 bytes long, little endian unsigned
    //Bytes 18 - 19:
    var info3 = bufferpack.unpack('<H', data, 18);
    //End of header.

    //The above code runs fine and returns the expected values correctly. 

    //However, the next section of data comes in as conditional and presents
    //plenty of problems:

    //Luckily, I am given the length of the next piece of data.
    var firstSectionLength = bufferpack.unpack('<H', data, 20);
    //Next, three data packets will be sent, each containing 1-30 
    //Bytes of data. This is my current solution:
    var firstSectionInfo = bufferpack.unpack((modemInfoLength).toString() + 's', data, 22);
    //The next two information sections follow the same patter as the above.
    console.log(firstSectionInfo);
;

此代码将向控制台记录一个数组,该数组将每条数据放入第一个索引中,以“/u0000”分隔。由于它是一个数组,我无法简单地 .split() 它。但是,如果我 .toString() 数组,它将返回一个字符串,但会删除“/u0000”部分,让我将所有数据串在一起,无法拆分它们。由于它们的长度都是可变的,因此我无法制作地图来提取字符串的切片作为有用信息。

有没有办法更有效地解析数据包或可靠地解析索引数组值?

我要补充一下,以前的 python 代码是用来做解析的:

def dataPacket(self, data, (host, port)):
    #I'll skip directly to how the first information section is parsed
    #...
    #Recall the header is fixed at 20 bytes.
    firstInfoSectionLength = unpack('H', data[20:22])
    firstInfoSectionBegin = 22
    firstInfoSectionEnd = firstInfoSectionBegin + firstInfoSectionLength[0]
    firstInfoSection = '%r' % data[firstInfoSectionBegin:firstInfoSectionEnd]
    firstInfoSection = firstInfoSection.strip("'")
    firstInfoSection = firstInfoSection.split('\\x00')
    data1 = firstInfoSection[0]
    data2 = firstInfoSection[1]
    data3 = firstInfoSection[2]
    data4 = firstInfoSection[3]
    data5 = firstInfoSection[4]

您会注意到,python 程序通过不同的参数解析变量信息长度,然后我需要在 node.js 程序中解析。

谢谢

【问题讨论】:

【参考方案1】:

如果您在firstSectionInfo 中拥有的是这样的:

['ab\u0000cd\u0000']

我假设您想拆分数组中的唯一值。所以你可以这样做:

['ab\u0000cd\u0000'][0].split('\u0000')

您将获得值 'ab''cd'''

(顺便说一句,你一直在写/u0000,但这不能对应Python的\x00。)

【讨论】:

不幸的是,它不是返回数组 ['a','b','/u0000','c','d','/u0000'] 而是返回数组 ['ab/ u0000cd/u0000'] 都在索引数组[0]您在评论中的“它”指的是什么?你说的是firstSectionInfo的内容吗? 是的,调用console.log时的var firstSectionInfo会打印出我在上面评论中提到的内容

以上是关于使用 Node.js 进行条件二进制解包的主要内容,如果未能解决你的问题,请参考以下文章

struct--二进制数据结构的打包与解包

使用 struct.unpack_from() 解包混合二进制数据

Node.js(十四)——Net模块之Buffer

node.js 中的二进制 RPC

[Node.js]Buffer

Linux系统中安装二进制的Node.js包