Какой язык для бинарного, как Perl для текста? - PullRequest
15 голосов
/ 14 июня 2009

Я ищу язык сценариев (или программирования более высокого уровня) (или, например, модули для Python или аналогичных языков) для легкого анализа и манипулирования двоичными данными в файлах (например, дампы ядра), во многом как Perl позволяет очень плавно манипулировать текстовыми файлами .

Вещи, которые я хочу сделать, включают представление произвольных порций данных в различных формах (двоичных, десятичных, шестнадцатеричных), преобразование данных из одной последовательности в другую и т. Д. То есть вещи, для которых вы обычно используете C или сборку, но Я ищу язык, который позволяет очень быстро писать крошечные кусочки кода для очень специфичных, одноразовых целей.

Есть предложения?

Ответы [ 11 ]

27 голосов
/ 14 июня 2009

Вещи, которые я хочу сделать, включают представление произвольных порций данных в различных формах (двоичных, десятичных, шестнадцатеричных), преобразование данных из одной последовательности в другую и т. Д. То есть вещи, для которых вы обычно используете C или сборку, но Я ищу язык, который позволяет очень быстро писать крошечные кусочки кода для очень специфичных, одноразовых целей.

Ну, хотя это может показаться нелогичным, я обнаружил, что erlang очень хорошо подходит для этого, в частности, благодаря мощной поддержке сопоставления с шаблоном , даже для байтов и битов. (называется " Синтаксис битов Эрланга "). Что позволяет очень легко создавать даже очень продвинутые программы, которые занимаются проверкой и манипулированием данными на байтовом и даже на битовом уровнях:

С 2001 года функциональный язык Erlang поставляется с байтово-ориентированным типом данных (называемым двоичным) и конструкциями для сопоставления с образцом в двоичном файле.

И процитировать informIT.com :

(Erlang) Сопоставление с образцом действительно начинает становиться весело в сочетании с двоичным тип. Рассмотрим приложение, которое получает пакеты из сети и затем обрабатывает их. Четыре байта в пакет может быть сетевым порядком байтов идентификатор типа пакета. В Эрланге ты просто нужно один процессПакет функция, которая может преобразовать это в структура данных для внутреннего обработка. Это выглядело бы что-то как это:

processPacket(<<1:32/big,RestOfPacket>>) ->
    % Process type one packets
    ...
;
processPacket(<<2:32/big,RestOfPacket>>) ->
    % Process type two packets
    ...

Итак, erlang со встроенной поддержкой сопоставления с образцом и функциональным языком довольно выразителен, см., Например, реализацию ueencode в erlang:

uuencode(BitStr) ->
<< (X+32):8 || <<X:6>> <= BitStr >>.
uudecode(Text) ->
<< (X-32):6 || <<X:8>> <= Text >>.

Для ознакомления см. Двоичные файлы и обобщенные интерпретации в Erlang . Вы также можете проверить некоторые из следующих указателей:

5 голосов
/ 14 июня 2009

perl's pack и unpack ?

4 голосов
/ 07 июля 2009

Модуль Python bitstring был написан для этой цели. Он позволяет вам брать произвольные кусочки двоичных данных и предлагает ряд различных интерпретаций через свойства Python. Он также предоставляет множество инструментов для построения и изменения двоичных данных.

Например:

>>> from bitstring import BitArray, ConstBitStream
>>> s = BitArray('0x00cf')                           # 16 bits long
>>> print(s.hex, s.bin, s.int)                       # Some different views
00cf 0000000011001111 207
>>> s[2:5] = '0b001100001'                           # slice assignment
>>> s.replace('0b110', '0x345')                      # find and replace
2                                                    # 2 replacements made
>>> s.prepend([1])                                   # Add 1 bit to the start
>>> s.byteswap()                                     # Byte reversal
>>> ordinary_string = s.bytes                        # Back to Python string

В битовой строке также есть функции для побитового чтения и навигации, как в файлах; фактически это можно сделать прямо из файла, не считывая его в память:

>>> s = ConstBitStream(filename='somefile.ext')
>>> hex_code, a, b = s.readlist('hex:32, uint:7, uint:13')
>>> s.find('0x0001')         # Seek to next occurence, if found
True

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

4 голосов
/ 15 июня 2009

Посмотрите на цепочку битов Python , она выглядит именно так, как вы хотите:)

3 голосов
/ 14 июня 2009

Я использую 010 Editor , чтобы постоянно просматривать двоичные файлы для просмотра двоичных файлов. Он специально предназначен для работы с двоичными файлами.

Он имеет простой в использовании язык сценариев c-like для анализа двоичных файлов и представления их в очень удобочитаемой форме (в виде дерева, полей, закодированных цветом, и тому подобное) Есть несколько примеров скриптов для разбора zipfiles и bmpfiles.

Всякий раз, когда я создаю двоичный формат файла, я всегда делаю небольшой скрипт для редактора 010 для просмотра файлов. Если у вас есть несколько заголовочных файлов с некоторыми структурами, создание считывателя для двоичных файлов занимает считанные минуты.

2 голосов
/ 14 июня 2009

В стандартной библиотеке Python есть то, что вам нужно - в частности, модуль array позволяет легко считывать части двоичных файлов, порядковый номер подкачки и т. Д .; модуль struct позволяет более детально интерпретировать двоичные строки. Однако ни один из них не настолько богат, как вам требуется: например, для представления одних и тех же данных в виде байтов или полуслов необходимо скопировать их между двумя массивами (стороннее дополнение numpy гораздо мощный для интерпретации одной и той же области памяти несколькими различными способами) и, например, для отображения некоторых байтов в шестнадцатеричном формате, нет ничего более «связанного», кроме простого цикла или понимания списка, такого как [hex(b) for b in thebytes[start:stop]]. Я подозреваю, что существуют сторонние модули многократного использования, чтобы еще больше облегчать такие задачи, но я не могу указать вам на один ...

2 голосов
/ 14 июня 2009

Почему бы не использовать интерпретатор C? Я всегда использовал их, чтобы поэкспериментировать с фрагментами, но вы могли бы использовать их для написания сценария, описанного вами, без особых проблем.

Мне всегда нравились EiC . Это было мертвым, но проект был недавно возрожден. EiC удивительно способен и достаточно быстр. Существует также CINT . Оба могут быть скомпилированы для разных платформ, хотя я думаю, что CINT нуждается в Cygwin для Windows.

2 голосов
/ 14 июня 2009

Подойдет любой язык программирования высокого уровня с функциями упаковки / распаковки. Все 3 Perl, Python и Ruby могут это сделать. Это вопрос личных предпочтений. Я написал несколько двоичных разборов в каждом из них и почувствовал, что Ruby наиболее прост / элегантен для этой задачи.

1 голос
/ 15 июня 2009

Ну, если скорость не имеет значения, и вы хотите perl, тогда переведите каждую строку двоичного файла в строку символов - 0 и 1. Да, я знаю, что в двоичном коде нет перевода строки :), но, вероятно, у вас есть фиксированный размер - например, байт или какой-то другой блок, с помощью которого вы можете разбить двоичный двоичный объект.

Затем просто используйте обработку строки perl для этих данных:)

1 голос
/ 15 июня 2009

Forth также может быть довольно хорош в этом, но это немного загадочно.

...