распаковать структурированные двоичные данные с помощью Python - PullRequest
0 голосов
/ 14 октября 2018

Я очень часто использую пакет struct для анализа двоичных данных, взятых из структур C, но я несколько раз достигал пределов этого:

  • , когда моя исходная структура дополняется32-битная архитектура, в то время как python установлен в 64-битном дистрибутиве
  • , когда деревья структур используются
  • , когда структуры содержат указатели (что также является проблемой 32 против 64 бит)

Поэтому я иногда получаю вручную свои данные, одно число за другим struct.unpack_from('<one element>', ...), но это действительно медленно!

Какой наилучший подход для решения этой проблемы, учитывая тот факт, что яЯ могу создать файл, который содержит для каждой переменной: имя, тип, размер и смещение ...

Было бы легко создать функцию, подобную struct.unpack(), которая принимает такиепроизвольное описание?Или у вас есть альтернативное решение?

Вот пример кода C, который генерирует проблемный случай:

#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>

typedef struct {
    uint32_t a;
    uint8_t b;
    float c;
} alpha_T;

typedef struct {
    uint32_t a; 
    int32_t * b;
    double c;
} beta_T;

typedef struct {
    alpha_T a;
    beta_T b;
} gamma_T;

typedef struct {
    uint32_t a_a;
    uint8_t a_b;
    float a_c;
    uint32_t b_a;   
    int32_t * b_b;
    double b_c;

} zeta_T;

int main() {
    gamma_T m;
    size_t p = (size_t) & m;

    printf("m.a.a @%ld\n", (size_t) &(m.a.a) - p);
    printf("m.a.b @%ld\n", (size_t) &(m.a.b) - p);
    printf("m.a.c @%ld\n", (size_t) &(m.a.c) - p);
    printf("m.b.a @%ld\n", (size_t) &(m.b.a) - p);
    printf("m.b.b @%ld\n", (size_t) &(m.b.b) - p);
    printf("m.b.c @%ld\n", (size_t) &(m.b.c) - p);

    zeta_T z;
    size_t n = (size_t) & z;

    printf("z.a_a @%ld\n", (size_t) &(z.a_a) - n);
    printf("z.a_b @%ld\n", (size_t) &(z.a_b) - n);
    printf("z.a_c @%ld\n", (size_t) &(z.a_c) - n);
    printf("z.b_a @%ld\n", (size_t) &(z.b_a) - n);
    printf("z.b_b @%ld\n", (size_t) &(z.b_b) - n);
    printf("z.b_c @%ld\n", (size_t) &(z.b_c) - n);
}

Вывод этого:

m.a.a @0
m.a.b @4
m.a.c @8
m.b.a @16
m.b.b @24
m.b.c @32

z.a_a @0
z.a_b @4
z.a_c @8
z.b_a @12
z.b_b @16
z.b_c @24

Если я использую простой struct.Struct('IBfIpd'), я пропускаю дополнительное заполнение между m.a.c и m.b.a, и мы можем увидеть разницу с сглаженным эквивалентом z.

Так что мое текущее решение для декодирования mba,подготовить предыдущую таблицу для m (с буквой типа) и использовать struct.unpack_from('I', 16, n)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...