Binary data dissector and generator
Find a file
lemontree55 955093709d
All checks were successful
ci/woodpecker/push/spec/1 Pipeline was successful
ci/woodpecker/push/spec/5 Pipeline was successful
ci/woodpecker/push/spec/3 Pipeline was successful
ci/woodpecker/push/spec/2 Pipeline was successful
ci/woodpecker/push/spec/4 Pipeline was successful
ci/woodpecker/push/yardoc-test Pipeline was successful
Array: Fix yardoc
2026-01-07 16:00:27 +01:00
.woodpecker [ci] yard-doctest is run on ruby 3.4 image 2025-12-28 13:15:41 +01:00
bin Update bin/console 2024-11-24 17:40:12 +01:00
lib Array: Fix yardoc 2026-01-07 16:00:27 +01:00
spec [Array] Add #counter, #length, #pop, #shift, #unshift 2026-01-07 15:59:51 +01:00
.gitignore Initial commit 2024-07-14 11:48:30 +02:00
.rspec Initial commit 2024-07-14 11:48:30 +02:00
.rubocop.yml Add yard-lint as dependency. Bump ruby version to 3.1 2025-11-21 21:02:18 +01:00
.yard-lint.yml Add yard-lint as dependency. Bump ruby version to 3.1 2025-11-21 21:02:18 +01:00
.yardopts [doc] U!pdate yard doc and check examples 2025-02-17 18:16:43 +01:00
bin_struct.gemspec Remove support for Ruby 3.0 2025-12-28 13:06:57 +01:00
CHANGELOG.md Bump version to 0.5.3 2026-01-07 09:54:36 +01:00
doctest_helper.rb [doc] U!pdate yard doc and check examples 2025-02-17 18:16:43 +01:00
Gemfile Remove support for Ruby 3.0 2025-12-28 13:06:57 +01:00
LICENSE.txt Initial commit 2024-07-14 11:48:30 +02:00
Rakefile [CI] Fix Rakefile 2025-08-14 11:14:19 +02:00
README.md Update README.md 2025-08-14 12:40:25 +02:00

Gem Version status-badge

BinStruct

BinStruct provides a simple way to create and dissect binary data. It is an extraction from PacketGen 3.x Fields.

Installation

Installation using RubyGems is easy:

gem install bin_struct

Or add it to a Gemfile:

gem 'bin_struct'

Usage

Create a struct

To create a BinStruct, create a new class inheriting from BinStruct::Struct. Then, defines struct attributes using .define_attr. .define_bit_attr may also be used to define bit field attributes.

require 'bin_struct'

class IPHeader < BinStruct::Struct
  # Define a bir field, defaulting to 0x45, and splitted in 2 sub-fields: version and ihl,
  # 4-bit size each
  define_bit_attr :u8, default: 0x45, version: 4, ihl: 4
  # Define a 8-bit unsigned integer named tos
  #  1st argument: a symbol to define attribute name
  #  2nd argument: a class to define attribute type. May be a type provided by BinStruct,
  #                or a user-defined class inheriting from one of these classes
  #  others arguments: options. Here, :default defines a default value for the attribute.
  define_attr :tos, BinStruct::Int8, default: 0
  # Define a 16-bit unsigned integer named length. Default to 20.
  define_attr :length, BinStruct::Int16, default: 20
  # Define a 16-bir unsigned integer named id. It is initialized with a random number
  define_attr :id, BinStruct::Int16, default: ->(_) { rand(65_535) }
  # Define a bit field composed of 4 subfields of 1, 1, 1 and 13 bit, respectively
  define_bit_attr :frag, flag_rsv: 1, flag_df: 1, flag_mf: 1, fragment_offset: 13
  # Define TTL field, a 8-bit unsigned integer, default to 64
  define_attr :ttl, BinStruct::Int8, default: 64
  # Define protocol field (8-bit unsigned integer)
  define_attr :protocol, BinStruct::Int8
  # Define checksum field (16-bit unsigned integer), default to 0
  define_attr :checksum, BinStruct::Int16, default: 0
  # Source and destination addresses, defined as array of 4 8-bit unsigned integers
  define_attr :src, BinStruct::ArrayOfInt8, length_from: -> { 4 }
  define_attr :dst, BinStruct::ArrayOfInt8, length_from: -> { 4 }
end

Parse a binary string

# Initialize struct from a binary string
ip = IPHeader.new.read("\x45\x00\x00\x14\x43\x21\x00\x00\x40\x01\x00\x00\x7f\x00\x00\x01\x7f\x00\x00\x01".b)

# Access some fields
p ip.version     #=> 4
p ip.ihl         #=> 5
p ip.id.to_s(16) #=> "4321"
p ip.protocol    #=> 1
p ip.src.map { |byte| byte.to_i }.join('.') #=> "127.0.0.1"
> p IPHeader.new.read("\x45\x00\x00\x14\x43\x21\x00\x00\x40\x01\x00\x00\x7f\x00\x00\x01\x7f\x00\x00\x01")
-- IPHeader -----------------------------------------------------------
          BitAttr8               u8: 69               (0x45)
                                     version:4 ihl:5
              Int8              tos: 0                (0x00)
             Int16           length: 20               (0x0014)
             Int16               id: 17185            (0x4321)
         BitAttr16             frag: 0                (0x0000)
                                     flag_rsv:0 flag_df:0 flag_mf:0 fragment_offset:0
              Int8              ttl: 64               (0x40)
              Int8         protocol: 1                (0x01)
             Int16         checksum: 0                (0x0000)
       ArrayOfInt8              src: 127,0,0,1
       ArrayOfInt8              dst: 127,0,0,1

Generate a binary string

# Create a new struct with some fields initialized
ip = IPHeader.new(tos: 42, id: 0x1234)

# Initialize fields after creation
ip.src = [192, 168, 1, 1]
ip.dst = [192, 168, 1, 2]

# Generate binary string
ip.to_s

License

The gem is available as open source under the terms of the MIT License.