16

我正在寻找一种脚本(或更高级别的编程)语言(或例如 Python 或类似语言的模块)来轻松分析和操作文件(例如核心转储)中的二进制数据,就像 Perl 允许非常流畅地操作文本文件一样。

我想做的事情包括以各种形式(二进制、十进制、十六进制)呈现任意数据块,将数据从一种字节序转换为另一种字节序,等等。也就是说,你通常会使用 C 或汇编的东西,但我寻找一种允许非常快速地为高度特定的一次性目的编写小段代码的语言。

有什么建议么?

4

11 回答 11

29

我想做的事情包括以各种形式(二进制、十进制、十六进制)呈现任意数据块,将数据从一种字节序转换为另一种字节序,等等。也就是说,你通常会使用 C 或汇编的东西,但我寻找一种允许非常快速地为高度特定的一次性目的编写小段代码的语言。

好吧,虽然它可能看起来违反直觉,但我发现erlang非常适合这种情况,即由于它对模式匹配的强大支持,甚至对字节和位(称为“ Erlang 位语法”)。这使得创建甚至非常高级的程序来处理检查和操作字节甚至位级别的数据变得非常容易:

自 2001 年以来,函数式语言 Erlang 带有面向字节的数据类型(称为二进制)和对二进制进行模式匹配的结构。

并引用informIT.com

(Erlang) 当与二进制类型结合使用时,模式匹配真的开始变得有趣了。考虑一个从网络接收数据包然后处理它们的应用程序。数据包中的四个字节可能是网络字节顺序数据包类型标识符。在 Erlang 中,您只需要一个 processPacket 函数即可将其转换为用于内部处理的数据结构。它看起来像这样:

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

因此,erlang 具有对模式匹配的内置支持,并且它是一种函数式语言,具有很强的表现力,例如,参见 erlang 中 ueencode 的实现:

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

有关介绍,请参阅Erlang 中的 Bitlevel Binaries and Generalized Comprehensions 。您可能还想查看以下一些提示:

于 2009-06-14T19:09:23.420 回答
6

perl 的打包和解

于 2009-06-14T18:38:44.117 回答
4

看看python bitstring,它看起来正是你想要的:)

于 2009-06-15T05:00:40.980 回答
4

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

还有一些具有不同字节顺序的视图以及交换字节顺序的能力等等——看看手册

于 2009-07-06T21:54:22.397 回答
3

我一直在使用010 Editor查看二进制文件来查看二进制文件。它特别适合处理二进制文件。

它有一种易于使用的类 c 脚本语言来解析二进制文件并以非常易读的方式呈现它们(作为树,按颜色编码的字段,类似的东西)。有一些示例脚本可以解析 zipfile 和 bmpfile。

每当我创建二进制文件格式时,我总是为 010 编辑器制作一个小脚本来查看文件。如果您有一些带有一些结构的头文件,那么制作二进制文件的阅读器只需几分钟。

于 2009-06-14T19:01:59.350 回答
2

任何具有打包/解包功能的高级编程语言都可以。所有 3 Perl、Python 和 Ruby 都可以做到。这是个人喜好的问题。我在其中的每一个中都写了一些二进制解析,并且觉得 Ruby 最简单/最优雅地完成这项任务。

于 2009-06-14T19:00:42.380 回答
2

为什么不使用 C 解释器?我总是用它们来试验片段,但你可以用一个来编写你描述的东西,而不会有太多麻烦。

我一直很喜欢EiC。它已经死了,但该项目最近又复活了。EiC 的能力出人意料,而且速度相当快。还有CINT。两者都可以针对不同的平台进行编译,尽管我认为 CINT 在 Windows 上需要 Cygwin。

于 2009-06-14T19:00:47.213 回答
2

Python 的标准库有一些你需要的东西——特别是数组模块让你可以轻松地读取部分二进制文件、交换字节顺序等;struct模块允许对二进制字符串进行更细粒度的解释。但是,两者都没有您需要的那么丰富:例如,要将相同的数据显示为字节或半字,您需要在两个数组之间复制它(numpy第三方插件对于解释相同的区域要强大得多内存以几种不同的方式),例如,要以十六进制显示一些字节,除了简单的循环或列表理解(例如[hex(b) for b in thebytes[start:stop]]. 我怀疑有可重用的第三方模块来进一步促进此类任务,但我不能指出你...

于 2009-06-14T19:01:40.833 回答
1

Forth 在这方面也可以做得很好,但它有点神秘。

于 2009-06-14T20:13:34.373 回答
1

好吧,如果速度不是一个考虑因素,并且你想要 perl,那么将每一行二进制转换为一行字符 - 0 和 1。是的,我知道二进制文件中没有换行符:) 但大概你有一些固定的大小——例如按字节或其他单位,你可以用它来分解二进制 blob。

然后只需对该数据使用 perl 字符串处理 :)

于 2009-06-15T12:39:51.343 回答
0

如果您正在进行二进制级别的处理,它的级别非常低,可能需要非常高效并且具有最小的依赖项/安装要求。

所以我会选择 C ​​- 很好地处理字节 - 你可能可以谷歌搜索一些处理字节的库包。

使用像 Erlang 这样的东西会引入低效、依赖和其他你可能不希望使用低级库的包袱。

于 2009-06-14T19:23:10.860 回答