Конструкт (библиотека Python)
Эта статья нуждается в дополнительных цитатах для проверки . ( август 2023 г. ) |
Construct — это библиотека Python для построения и деконструкции структур данных декларативным способом . В этом контексте конструирование или построение относится к процессу преобразования ( сериализации ) программного объекта в двоичное представление. Деконструкция или синтаксический анализ относится к противоположному процессу преобразования (десериализации) двоичных данных в программный объект. Декларативность означает, что пользовательский код определяет структуру данных вместо соглашения о написании процедурного кода для достижения цели. Construct может беспрепятственно работать с битов и байтов детализацией данных на уровне и различным упорядочением байтов .
Преимущества
[ редактировать ]Использование декларативного кода имеет множество преимуществ. Например, тот же код, который можно анализировать, можно также и собирать (симметрично), отладка и тестирование намного проще (до некоторой степени доказуемо), легко создавать новые конструкции (обертывать компоненты) и многое другое. Если кто-то знаком с C (языком программирования) , он может думать о конструкциях как о приведении из char *
к struct foo *
и наоборот, вместо того, чтобы писать код, распаковывающий данные.
Пример
[ редактировать ]В следующем примере показано, как TCP/IP стек протоколов можно определить с помощью Construct. Некоторый код опущен для краткости и простоты. Также обратите внимание, что следующий код — это просто код Python, создающий объекты.
Сначала Ethernet заголовок (уровень 2):
ethernet = Struct(
"destination" / Bytes(6),
"source" / Bytes(6),
"type" / Enum(Int16ub,
IPv4=0x0800,
ARP=0x0806,
RARP=0x8035,
X25=0x0805,
IPX=0x8137,
IPv6=0x86DD,
),
)
Далее IP- заголовок (уровень 3):
ip = Struct(
"header" / BitStruct(
"version" / Const(Nibble, 4),
"header_length" / Nibble,
),
"tos" / BitStruct(
"precedence" / Bytes(3),
"minimize_delay" / Flag,
"high_throuput" / Flag,
"high_reliability" / Flag,
"minimize_cost" / Flag,
Padding(1),
),
"total_length" / Int16ub,
# ...
)
И, наконец, TCP- заголовок (уровень 4):
tcp = Struct(
"source" / Int16ub,
"destination" / Int16ub,
"seq" / Int32ub,
"ack" / Int32ub,
# ...
)
Теперь определим иерархию стека протоколов. Следующий код «связывает» каждую пару соседних протоколов в отдельный блок. Каждое такое устройство «выберет» подходящий следующий уровень на основе содержащегося в нем протокола.
layer4tcp = Struct(
tcp,
# ... payload
)
layer3ip = Struct(
ip,
"next" / Switch(this.protocol,
{
"TCP" : layer4tcp,
}
),
)
layer2ethernet = Struct(
ethernet,
"next" / Switch(this.type,
{
"IP" : layer3ip,
}
),
)
На этом этапе код может разобрать захваченные кадры TCP/IP на «пакетные» объекты и преобразовать эти пакеты обратно в двоичное представление.
tcpip_stack = layer2ethernet
packet = tcpip_stack.parse(b"...raw captured packet...")
raw_data = tcpip_stack.build(packet)
Порты и спин-оффы
[ редактировать ]Перл
[ редактировать ]Данные::ParseBinary [ 1 ] — это модуль CPAN , который возник как порт Construct на язык программирования Perl . ( см. его основной документ POD для вдохновения ). Начиная с первоначальной версии, некоторые части исходного API устарели.
Ява
[ редактировать ]Порт на Java доступен на GitHub. [ 2 ] Примеры на Java, заголовок Ethernet (уровень 2):
Construct ethernet_header = Struct("ethernet_header",
MacAddress("destination"),
MacAddress("source"),
Enum(UBInt16("type"),
"IPv4", 0x0800,
"ARP", 0x0806,
"RARP", 0x8035,
"X25", 0x0805,
"IPX", 0x8137,
"IPv6", 0x86DD,
"_default_", Pass
));
Ссылки
[ редактировать ]- ^ «Data::ParseBinary — еще один парсер бинарных структур — Metacpan.org» . Metacpan.org . Проверено 29 августа 2023 г.
- ^ Зильоли, Эмануэле (29 декабря 2022 г.), ZiglioUK/construct , получено 29 августа 2023 г.