Условная двоичная распаковка с Node.js

Мне было поручено создать программу node.js, которая имеет три основных компонента: прослушивать входящие данные (которые поступают в виде упакованного двоичного файла), распаковывать и анализировать эти данные, а затем отправлять их в базу данных postgreSQL. Проблема, с которой я столкнулся, заключается в том, что все узлы библиотеки npm, предлагаемые в настоящее время, не очень хорошо работают с условными форматами распаковки.

Данные поступают в общем формате:

  1. Заголовок Эта часть фиксируется в 20 байтов на каждый входящий пакет данных и, таким образом, легко анализировать.

  2. Первый информационный раздел. Это имеет переменную длину.

  3. Второй информационный раздел. Это имеет переменную длину.

  4. Третий информационный раздел. Это имеет переменную длину.

К счастью, мне дается длина каждого раздела как первые два байта в каждом случае.

У меня есть руководство, чтобы сказать мне, как долго каждый пакет информации будет находиться в заголовке, используя библиотеки bufferpack и двоичные библиотеки 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 но это не может соответствовать питону \x00.)

Другие вопросы по тегам