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.1.tar.gz (161.1 kB view details)

Uploaded Source

Built Distributions

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

Uploaded Source

BinField-0.8.1-py3.5.egg (24.9 kB view details)

Uploaded Source

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

Uploaded Source

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

Uploaded Source

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

Uploaded Source

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

Uploaded Source

File details

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

File metadata

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

File hashes

Hashes for BinField-0.8.1.tar.gz
Algorithm Hash digest
SHA256 13f0815b867fdbc3c7d45e573c6f22dd494834b73e7cfb01268e808303832236
MD5 9aab9070a8d1462c54f6c1c075229209
BLAKE2b-256 49c0176faf20460a307d50fe4c633de61a8935cb5204ad67c3a5f16551c900c5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for BinField-0.8.1-py3.6-linux-x86_64.egg
Algorithm Hash digest
SHA256 3996214d9a5dff3119c76684cac9f1db3590f5c27fcbc95cafdba68ebaa3e7e4
MD5 7ae6b7b729744ade88d4b180108cb982
BLAKE2b-256 bd1ad743cc9dd2b8ec6a628a238b14d9098638a6ae4c6639a2ce162e289e37a5

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for BinField-0.8.1-py3.5.egg
Algorithm Hash digest
SHA256 dd600181227d434ce5fbc0279e703d597932a2e8d14e23b9098af687c52b76e6
MD5 8d37a36eb54adf75bab68056e920ec8b
BLAKE2b-256 810520b9c35c4082636b0b948a2c5ca8ab40ba457245c4153eccfffb49836016

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for BinField-0.8.1-py3.5-linux-x86_64.egg
Algorithm Hash digest
SHA256 e3bd7742a26bd1fff5b1495f3e6bb1cbc6a1cf6bb99f56a86b74b5fa06f30d7e
MD5 8089ab1e4b0774d8abb067c9cdd6b94d
BLAKE2b-256 9bac709b81187d804f44f4b7709ca8ee0cf359cc1258083590a8a3e6f93aaadd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for BinField-0.8.1-py3.4-linux-x86_64.egg
Algorithm Hash digest
SHA256 532ae499c9e623c0aab650af2907d3cd848db14cb0f57399742c14c2c6ee0037
MD5 440b97cb2e01e4c4a9dd032e91442f3c
BLAKE2b-256 0653abe2b74b9c05c3270968751a2def49d6bdee6247a2576734e561fc923250

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for BinField-0.8.1-py2.7.egg
Algorithm Hash digest
SHA256 1d19fbfeca677c2850654b1cec4c46efd9401e323322d4283ef1b7da137914c6
MD5 775762388ba12490f9bf39449c99b3f8
BLAKE2b-256 3c846cf1c3c754cc4216177d2b5185bc0684ca8770c0d515da7d835a69bac5ee

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for BinField-0.8.1-py2.7-linux-x86_64.egg
Algorithm Hash digest
SHA256 7933fb41ac6e5f1e6515f5b0b3c51c6b57b93d9b1786d5a1d8d7f5fafaf476a2
MD5 c974bcad55e28e1456f93ba203ee4397
BLAKE2b-256 903ea5bfc83272e5c978d81309c2f6cbf127997e4f50938648fc6bf0fa590495

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