代码之家  ›  专栏  ›  技术社区  ›  Eric Hansander Joe Harris

什么语言是二进制的,就像Perl是文本的?

  •  15
  • Eric Hansander Joe Harris  · 技术社区  · 15 年前

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

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

    有什么建议吗?

    11 回复  |  直到 9 年前
        1
  •  27
  •   Yaakov Ellis NevilleDNZ    11 年前

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

    嗯,虽然这看起来有点违反直觉,但我发现 erlang 非常适合这一点,也就是说,由于其强大的支持 pattern matching ,即使是字节和位(称为 Erlang Bit Syntax “”。这使得很容易创建甚至非常高级的程序来处理在字节上甚至在位级别上检查和操作数据:

    自2001年以来,函数语言erlang具有面向字节的数据类型(称为binary),并且具有在二进制文件上进行模式匹配的构造。

    并引用 informIT.com :

    (Erlang)模式匹配真正开始 与二进制结合时很有趣 类型。考虑一个应用程序 从网络接收数据包并 然后处理它们。中的四个字节 数据包可能是网络字节顺序 数据包类型标识符。在Erlang,你 只需要一个进程包 可以将此转换为 内部数据结构 处理。看起来会有点像 这样地:

    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 。您可能还需要签出以下一些指针:

        2
  •  5
  •   toolkit    15 年前

    珀尔 pack unpack ?

        3
  •  4
  •   Portablejim    9 年前

    蟒蛇 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
  •  4
  •   Portablejim    9 年前

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

        5
  •  3
  •   Wouter van Nifterick Andrey    15 年前

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

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

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

        6
  •  2
  •   Igor Krivokon    15 年前

    任何具有pack/unpack功能的高级编程语言都可以。所有3个Perl、Python和Ruby都可以做到。这是个人喜好的问题。我在每一篇文章中都写了一些二进制解析,并认为Ruby对于这项任务来说是最简单/最优雅的。

        7
  •  2
  •   R Ubben    15 年前

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

    我一直都喜欢 EiC . 它已经死了,但这个项目最近又重新启动了。主任工程师的能力惊人,速度也相当快。也有 CINT . 两者都可以针对不同的平台进行编译,尽管我认为CINT需要在Windows上使用Cygwin。

        8
  •  2
  •   Alex Martelli    15 年前

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

        9
  •  1
  •   Jason Baker    15 年前

    Fourth也很擅长这个,但有点神秘。

        10
  •  1
  •   Larry Watanabe    15 年前

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

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

        11
  •  0
  •   Larry Watanabe    15 年前

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

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

    使用像Erlang这样的工具会带来效率低下、依赖性和其他一些您可能不希望使用低级库的负担。