【问题标题】:What language is to binary, as Perl is to text?什么语言之于二进制,就像 Perl 之于文本?
【发布时间】:2009-06-14 18:31:23
【问题描述】:

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

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

有什么建议吗?

【问题讨论】:

  • 有趣。除了 asm 之外,我从未见过任何可以让您以这种方式处理二进制数据的东西。不过,不清楚它是否有用,因为二进制 blob 在没有解释的情况下或多或少是无用的。为什么不坚持使用 C 和按位运算,或者将二进制转换为 Perl 字符串?
  • 将二进制转换为字符串是我今天使用的(在 Python 或 Perl 中),但我觉得必须有一些更流畅、更强大的方法来实现这一点。我编辑了这个问题,试图解释为什么 C 不是答案,在这种情况下。
  • 如果这是专门关于核心转储和 C 编程的,您可能还想查看 GNU BFD:en.wikipedia.org/wiki/Binary_File_Descriptor_library
  • 我真正需要的是一个能理解水分蒸发器二进制语言的机器人。
  • 哈哈!我在首页看到了问题标题,并认为这是一个有趣的问题,您正在寻找一种语言,其中位的随机排列是有效的程序(就像 perl 对文本一样)!

标签: scripting binary-data patch fileparsing


【解决方案1】:

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

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

自 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 >>.

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

【讨论】:

  • 正是我要建议的。 Erlang 可以用二进制数据做很酷的事情。
  • 我也会在这个上使用 erlang
  • 很棒的答案!非常彻底。
  • 我同意。 Joe Armstrong 总是说他简直不敢相信没有其他语言在 Bits 上有 Bit 字面量和模式匹配。我完全同意。我的意思是,他们在每种 sh*tty 语言中都添加了浮点文字(实际上只有极少数科学程序员需要),但没有位语法?为什么?如果你有字符串文字和正则表达式,添加位字符串和位模式不会有什么大不了的,不是吗? [咆哮。]
【解决方案2】:

perl 的 packunpack ?

【讨论】:

  • 以及在二进制文件上运行愉快的正则表达式——这是我过去通过(ab)使用它帮助调试的一个特性。如果你想匹配的话,你可以打包/解包到二进制文件。最近的支持 unicode 的实现似乎把水弄得一团糟,但我认为所有这些都可以关闭。
【解决方案3】:

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

还有具有不同字节序的视图以及交换字节序的能力等等 - 看看manual

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

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

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

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

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

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

          【讨论】:

          • 这也是我的想法。我不知道 EiC,但 cint 接受一种松散的方言(当您没有为新引入的变量指定类型时,它会隐式(但仍然很强大)键入),这使得编写宏时更具 RAD 风格。
          【解决方案8】:

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

          【讨论】:

            【解决方案9】:

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

            【讨论】:

              【解决方案10】:

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

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

              【讨论】:

                【解决方案11】:

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

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

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

                【讨论】:

                • 实际上,速度对我来说并不是什么大问题,因为我主要使用它来“浏览”一些二进制 blob(例如核心转储或从流中记录的数据)或多或少交互方式,其大小通常可以以兆字节计算。您碰巧不知道任何值得一试的 C 类库​​包吗?
                猜你喜欢
                • 2012-12-22
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2010-11-10
                • 2014-03-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多