Skip to main content

Python BinField implementation for binary data manipulation

Project description

binfield

https://travis-ci.org/penguinolog/binfield.svg?branch=master https://coveralls.io/repos/github/penguinolog/binfield/badge.svg?branch=master Documentation Status https://img.shields.io/pypi/v/binfield.svg https://img.shields.io/pypi/pyversions/binfield.svg https://img.shields.io/pypi/status/binfield.svg https://img.shields.io/github/license/penguinolog/binfield.svg

Python binfield implementation for binary data manipulation.

Why? Python supports binary data manipulation via binary operations out of the box and it’s fast, but it’s hard to read and painful during prototyping, especially for complex (nested) structures.

This library is designed to fix this issue: it allows to operate with binary data like dict with constant indexes: you just need to define structure class and create an instance with start data. Now you can use indexes for reading and writing data

Pros:

  • Free software: Apache license

  • Open Source: https://github.com/penguinolog/binfield

  • Self-documented code: docstrings with types in comments

  • Tested: see badges on top

  • Support multiple Python versions:

Python 2.7
Python 3.4
Python 3.5
Python 3.6
PyPy
PyPy3
Jyton 2.7

Usage

Not mapped objects can be created simply from BinField class:

bf = BinField(42)

Data with fixed size should be created as a new class (type): Example on real data (ZigBee frame control field):

# Describe
class ZBFrameControl(binfield.BinField):
    _size_ = 16  # Optional, used as source for mask, if mask is not defined
    _mask_ = 0xFF7F  # Optional, used as source for size, if size is not defined
    FrameType = [0, 3]  # Enum
    Security = 3
    FramePending = 4
    AckRequest = 5
    PAN_ID_Compression = 6
    SecurityNumberSuppress = 8
    InformationPresent = 9
    DstAddrMode = [10, 12]
    FrameVersion =  [12, 14]
    SrcAddrMode = [14, 16]

# Construct from frame
# (limitation: endian conversion is not supported, make it using another tools)
frame = frame = ZBFrameControl(0x0803)  # Beacon request

>>> print(frame)
<2051 == 0x0803 == (0b0000100000000011 & 0b1111111111111111)
  FrameType             = <3 == 0x03 == (0b011 & 0b111)>
  Security               = <0 == 0x00 == (0b0 & 0b1)>
  FramePending           = <0 == 0x00 == (0b0 & 0b1)>
  AckRequest             = <0 == 0x00 == (0b0 & 0b1)>
  PAN_ID_Compression     = <0 == 0x00 == (0b0 & 0b1)>
  SecurityNumberSuppress = <0 == 0x00 == (0b0 & 0b1)>
  InformationPresent     = <0 == 0x00 == (0b0 & 0b1)>
  DstAddrMode            = <2 == 0x02 == (0b10 & 0b11)>
  FrameVersion           = <0 == 0x00 == (0b00 & 0b11)>
  SrcAddrMode            = <0 == 0x00 == (0b00 & 0b11)>

>>> repr(frame)
'ZBFrameControl(x=0x0803, base=16)'

>>> print(frame.FrameType)
<3 == 0x03 == (0b011 & 0b111)>  # Get nested structure: current is flat, so we have single value

# We can use slice to get bits from value: result type is always subclass of BinField
>>> repr(frame.FrameType[: 2])
'<FrameType_slice_0_2(x=0x03, base=16) at 0x7FD0ACA57408>'

>>> frame.FrameType == 3  # Transparent comparision with integers
True

>>> int(frame.FrameType)  # Painless conversion to int
3

>>> bool(frame.AckRequest)  # And bool
False

>>> print(frame[1: 5])  # Ignore indexes and just get few bits using slice
<1 == 0x01 == (0b0001 & 0b1111)>

>>> print(ZBFrameControl.AckRequest)  # Request indexes from created data type
5

>>> print(ZBFrameControl.DstAddrMode)  # Multiple bits too
slice(10, 12, None)

# Modification of nested data (if no type conversion was used) changes original object:
>>> frame.AckRequest = 1
>>> print(frame)
<2083 == 0x0823 == (0b0000100000100011 & 0b1111111101111111)
  FrameType              = <3 == 0x03 == (0b011 & 0b111)>
  Security               = <0 == 0x00 == (0b0 & 0b1)>
  FramePending           = <0 == 0x00 == (0b0 & 0b1)>
  AckRequest             = <1 == 0x01 == (0b1 & 0b1)>
  PAN_ID_Compression     = <0 == 0x00 == (0b0 & 0b1)>
  SecurityNumberSuppress = <0 == 0x00 == (0b0 & 0b1)>
  InformationPresent     = <0 == 0x00 == (0b0 & 0b1)>
  DstAddrMode            = <2 == 0x02 == (0b10 & 0b11)>
  FrameVersion           = <0 == 0x00 == (0b00 & 0b11)>
  SrcAddrMode            = <0 == 0x00 == (0b00 & 0b11)>
>

# But remember, that nested blocks has it's own classes
>>> repr(frame.DstAddrMode)
'<DstAddrMode(x=0x02, base=16) at 0x7FD0AD139548>'

>>> fr2 = ZBFrameControl(0xFFFF)
>>> repr(fr2)
'ZBFrameControl(x=0xFF7F, base=16)'  # Mask if applied, if defined

# Fields can be set only from integers
>>> frame.SrcAddrMode = fr2.SrcAddrMode
Traceback (most recent call last):
...
TypeError: BinField value could be set only as int

>>> repr(frame['FramePending'])  # __getitem__ and __setitem__ is supported
'<FramePending(x=0x00, base=16) at 0x7FD0ACAD3188>'

Nested structures are supported, if required. Definition example (not aligned with any real data):

class NestedMappedBinField(BinField):
    test_index = 0
    nested_block = {
        '_index_': (1, 6),
        'single_bit': 0,
        'multiple': (1, 3)
    }

>>> bf = NestedMappedBinField(0xFF)
# No _size_ and no _mask_ -> size is not limited,
# but indexes can not be changed after class creation
>>> print(bf)
<255 == 0xFF == (0b11111111)
  test_index   = <1 == 0x01 == (0b1 & 0b1)>
  nested_block =
    <31 == 0x1F == (0b11111 & 0b11111)
      single_bit = <1 == 0x01 == (0b1 & 0b1)>
      multiple   = <3 == 0x03 == (0b11 & 0b11)>
    >
>

# Get nested block: nested block is structured.
>>> print(bf.nested_block)
<31 == 0x1F == (0b11111 & 0b11111)
  single_bit = <1 == 0x01 == (0b1 & 0b1)>
  multiple   = <3 == 0x03 == (0b11 & 0b11)>
>

Note: negative indexes are not supported by design!

Testing

Main test mechanism for the package binfield uses tox. Test environments available:

pep8
py27
py34
py35
py36
pypy
pypy3
pylint
docs

CI systems

For code checking several CI systems are used in parallel:

  1. Travis CI: is used for checking: PEP8, pylint, bandit, installation possibility and unit tests. Also it publishes coverage on coveralls.

  2. coveralls: is used for coverage display.

CD system

Travis CI: is used for package delivery on PyPI.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

BinField-0.8.0.tar.gz (23.6 kB view details)

Uploaded Source

Built Distributions

BinField-0.8.0-py3.6-linux-x86_64.egg (648.0 kB view details)

Uploaded Source

BinField-0.8.0-py3.5.egg (24.8 kB view details)

Uploaded Source

BinField-0.8.0-py3.5-linux-x86_64.egg (614.9 kB view details)

Uploaded Source

BinField-0.8.0-py3.4-linux-x86_64.egg (636.7 kB view details)

Uploaded Source

BinField-0.8.0-py2.7.egg (24.0 kB view details)

Uploaded Source

BinField-0.8.0-py2.7-linux-x86_64.egg (559.8 kB view details)

Uploaded Source

File details

Details for the file BinField-0.8.0.tar.gz.

File metadata

  • Download URL: BinField-0.8.0.tar.gz
  • Upload date:
  • Size: 23.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for BinField-0.8.0.tar.gz
Algorithm Hash digest
SHA256 8bb6489fe74068202b1d6ab7ff5a206e1b1093857e62e3d02a7a7187782acb0b
MD5 0ff64950a436da81e0b1557c0964e5f4
BLAKE2b-256 2e77bbd397f377831af9130aab7638526b861f9bcbf3bbf8a9d0b2fa4eeb4dae

See more details on using hashes here.

File details

Details for the file BinField-0.8.0-py3.6-linux-x86_64.egg.

File metadata

File hashes

Hashes for BinField-0.8.0-py3.6-linux-x86_64.egg
Algorithm Hash digest
SHA256 da141f214035333d91178c8dbc1e8e8f86c437e748313919055452c2089fa40b
MD5 f35d071944d5fdaf48ebccaafc10b5d3
BLAKE2b-256 a1f1b949a4a6173514b5b86a8e5ef0851fb1cd9496e7d8840245beae64a480f0

See more details on using hashes here.

File details

Details for the file BinField-0.8.0-py3.5.egg.

File metadata

  • Download URL: BinField-0.8.0-py3.5.egg
  • Upload date:
  • Size: 24.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for BinField-0.8.0-py3.5.egg
Algorithm Hash digest
SHA256 10dc98a366a6e5c68044a8445f6e411f49ff8a9e5d0f7990ff32450a192a29fe
MD5 f1ec49851190c052ad6d4355fd20c1a0
BLAKE2b-256 83cb3d4582310cea08297a8f611aab58f84b16e7b8b576f22cad1077c6105d30

See more details on using hashes here.

File details

Details for the file BinField-0.8.0-py3.5-linux-x86_64.egg.

File metadata

File hashes

Hashes for BinField-0.8.0-py3.5-linux-x86_64.egg
Algorithm Hash digest
SHA256 4e929ec638346a04a8a3c2a9d8d23f4b5555d7e3084e4688a53b0bdffe0f2eba
MD5 906c96ca4c6e724961f9123efb8d18e0
BLAKE2b-256 ec27da392b7d55c099c1d3f58d27b13ae7ffcff3f3a6d682edf9163dcafa8e86

See more details on using hashes here.

File details

Details for the file BinField-0.8.0-py3.4-linux-x86_64.egg.

File metadata

File hashes

Hashes for BinField-0.8.0-py3.4-linux-x86_64.egg
Algorithm Hash digest
SHA256 f8eb87560e1965d8c239d39f5f28b243450beb49315690b2c0e158caef236e36
MD5 db40b74aa785d7aa755aa70a47dc07df
BLAKE2b-256 86223cf48907ff3bd36c1199e20c08d3dbe6ef2c40046ecae66796f954e34d7d

See more details on using hashes here.

File details

Details for the file BinField-0.8.0-py2.7.egg.

File metadata

  • Download URL: BinField-0.8.0-py2.7.egg
  • Upload date:
  • Size: 24.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for BinField-0.8.0-py2.7.egg
Algorithm Hash digest
SHA256 a145ddc16af833e106765ede6d8026404fb0567418ce7764c7f8a367b617800a
MD5 0ad712e8f5dc0df1ed2fc466ff12ecbc
BLAKE2b-256 cf61283b6b87049ef52d1f14dc49ffa3e17c8b60012c8d39aa53b67610487caa

See more details on using hashes here.

File details

Details for the file BinField-0.8.0-py2.7-linux-x86_64.egg.

File metadata

File hashes

Hashes for BinField-0.8.0-py2.7-linux-x86_64.egg
Algorithm Hash digest
SHA256 41b26e5abbc8873ec92c0786830ff9b1148d3a9dd4ee4a2e9a4d4b8a5a32b0a8
MD5 9f279627aa6fbb3781f67c78efe92351
BLAKE2b-256 1d1b2e5b59f268227a14c3c1edbeab0719a3aee074b2216b88bdfe58636959a6

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page