📅 You're Invited: Meet the Socket team at RSAC (April 28 – May 1).RSVP
Socket
Sign inDemoInstall
Socket

binary_parser

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

binary_parser

1.3.0
Rubygems
Version published
Maintainers
1
Created
Source

Ruby-Binary-Parser

Ruby-Binary-Parser is Ruby Gem library providing DSL for parsing binary-data, such as Image files, Video files, etc. Without operating bytes and bits complicatedly, you can parse and read binary-data generically and abstractly.

Description

This library can parse all kind of binary-data structures including non-fixed length of structures and nested structures. For generic parsing, loop and condition(if) statement to define structures is provided in this library. Of course, values of neighbor binary-data can be used as the other binary-data's specification of length.

Furthermore, this library handles all binary-data under the lazy evaluation. So you can read required parts of a binary-data very quickly even if whole of the binary-data is too big,

Notice

Currently, this library supports only READ of binary-data. So you cannot WRITE binary-data directly with this library.

Usage

Look at following examples to quickly understand how to use this library.

Install

$ gem install binary_parser

Example 1

Consider the following (temporary) binary structures which describe Image data.

MyImage (non-fixed length)
Data NameTypeBit LengthNumber Of Replications
heightUInt81
widthUInt81
RGB color bit-mapUInt8 * 3'height' * 'width'
has date?Flag11
dateMyDate31'has date?' is 1 => 1
else => 0
MyDate (31 bit)
Data NameTypeBit LengthNumber Of Replications
yearUInt131
monthUInt91
dayUInt91

You can define MyImage structure in ruby program as following code.

require 'binary_parser'

class MyDate < BinaryParser::TemplateBase
  require 'date'

  Def do
    data :year,  UInt, 13
    data :month, UInt, 9
    data :day,   UInt, 9
  end

  def to_date
    return Date.new(year.to_i, month.to_i, day.to_i)
  end
end

class MyImage < BinaryParser::TemplateBase
  Def do
    data :height, UInt, 8
    data :width,  UInt, 8

    # Loop statement
    TIMES var(:height), :i do
      TIMES var(:width), :j do
        data :R, UInt, 8
        data :G, UInt, 8
        data :B, UInt, 8
      end
    end

    data :has_date, Flag, 1

    # Condition statement
    # * If you want to check whether variable-name is valid, alternative expression
    #     IF cond(:has_date){|v| v.on?} do ~ end
    #   is also available.
    IF E{ has_date.on? } do
      data :date, MyDate, 31
    end
  end
end

And then you can parse and read binay-data of MyImage as follows.

File.open('my_image.bin', 'rb') do |f|
  image = MyImage.new(f.read)
  puts "Image size: #{image.height}x#{image.width}"
  ul = image.i[0].j[0]
  puts "RGB color at the first is (#{ul.R}, #{ul.G}, #{ul.B})"
  puts "Image date: #{image.date.to_date}"
end

If 'my_image.bin' is binary-data-file of [0x02, 0x02, 0xe7,0x39,0x62, 0x00,0x00,0x00, 0xe7,0x39,0x62, 0x00,0x00,0x00, 0x9f, 0x78, 0x08, 0x03], you can get output as follows.

Image size: 2x2
RGB color at the first is (231, 57, 98)
Image date: 2014-04-03

For your information, you can dump all binary-data's information as follows.

File.open('my_image.bin', 'rb') do |f|
  image = MyImage.new(f.read)
  image.show(true)
end

Example 2

You can also define other structures as follows.

class DefExample < BinaryParser::TemplateBase
  Def do
    data :loop_byte_length, UInt, 8

    # Loop until 'loop_byte_length' * 8 bits are parsed.
    SPEND var(:loop_byte_length) * 8, :list do

      data :length, UInt,   8

      # You can specify length by neigbor value.
      data :data,   Binary, var(:length) * 8
    end

    data :v1, UInt, 8
    data :v2, UInt, 8

    # Number of Condition variables is arbitary. 
    IF cond(:v1, :v2){|v1, v2| v1 == v2} do

      # +, -, *, / is available to specify length with variable.
      data :v3, UInt, 8 * (var(:v1) + var(:v2))
    end
  end
end

You can check this definition by giving some binary-data and calling show method as follows.

binary = [0x05, 0x01, 0xff, 0x02, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01].pack("C*")
i = DefExample.new(binary)
i.show(true)

Output for above checking-code is shown below.

*--------------------------------------------------------------------------------
loop_byte_length  Pos:      0  Len:      8  Type:       UInt  Cont: 5
list              Pos:      8  Len:     40  Type:   LoopList  Cont: list with 2 elements
  [0]
    *--------------------------------------------------------------------------------
    length  Pos:      0  Len:      8  Type:       UInt  Cont: 1
    data    Pos:      8  Len:      8  Type:     Binary  Cont: [0xff]
  [1]
    *--------------------------------------------------------------------------------
    length  Pos:      0  Len:      8  Type:       UInt  Cont: 2
    data    Pos:      8  Len:     16  Type:     Binary  Cont: [0xff, 0xff]
v1                Pos:     48  Len:      8  Type:       UInt  Cont: 1
v2                Pos:     56  Len:      8  Type:       UInt  Cont: 1
v3                Pos:     64  Len:     16  Type:       UInt  Cont: 257

Example 3

If you want to operate Stream-data, StreamTemplateBase class is useful. Define stream as follows.

class StreamExample < BinaryParser::StreamTemplateBase
  # Stream which consists of 4bytes-binary-datas.
  Def(4) do
    data :data1, UInt,   8
    data :data2, Binary, 24
  end
end

And then, get structures from the stream as follows.

File.open('my_image.bin', 'rb') do |f|
  stream = StreamExample.new(f)
  packet = stream.get_next
  puts "data1: #{packet.data1}, data2: #{packet.data2}"
  stream.get_next.show(true)
end

StreamTemplateBase has many useful methods to choose structures from the stream. If you want to know detail of these methods, please read documentation or concerned source-files.

Documentation

I'm sorry, but only RDoc (auto-generated documentation) is now available. For example, you can read RDoc on web browser by following operations.

$ gem install binary_parser
$ gem server
Server started at http://0.0.0.0:8808

Access shown address by web browser.

Versions

1.0.0 April 6, 2014
1.2.0 November 7, 2014

FAQs

Package last updated on 09 Mar 2015

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts