binteger module

binteger is a toolkit for manipulating integers in their binary (fixed-width) representation (big endian - most significant bits go first).

Documentation: https://binteger.readthedocs.io/

Code: https://github.com/hellman/binteger

Installation:

pip install binteger

This module is quite similar to bitstring (at PyPI): https://github.com/scott-griffiths/bitstring which is pretty awesome.

The difference is that the API is a bit more compact to aid simple conversions, such as:

>>> from binteger import Bin
>>> Bin(0x4142).bytes
b'AB'
>>> Bin(b'AB').int == 0x4142
True
>>> Bin(14, n=6).tuple
(0, 0, 1, 1, 1, 0)
>>> Bin(0x123, n=16).rol(8).hex
'2301'

Warning

binteger is optimized for convenience of use, rather than for performance.

class binteger.Bin(spec, n=None)[source]

An integer with a fixed-width binary representation.

Provides tools for working on binary representation.

Parameters
  • spec – Specifier for the integer: int, or list/tuple/str of 0/1 (binary representation), or bytes (to be unpacked).

  • n (int, optional) – Width of the binary representation.

int

Integer representation.

Type

int

n

Width of the binary representation.

Type

int

Examples

Creation:

>>> Bin(16).n
5
>>> Bin(16).int
16
>>> Bin(16, n=3)
Traceback (most recent call last):
ValueError: integer out of range
>>> Bin(b"AB")  # bytes are unpacked
Bin(0b0100000101000010, n=16)
>>> Bin("010")  # strings must be the binary representation
Bin(0b010, n=3)
>>> Bin("AB")  # strings must be 01-formed
Traceback (most recent call last):
ValueError: invalid literal for int() with base 10: 'A'

Outputting (formatting):

>>> str(Bin(16))
'10000'
>>> repr(Bin(16))
'Bin(0b10000, n=5)'
>>> str(Bin(16, 8))
'00010000'
>>> Bin(16).tuple
(1, 0, 0, 0, 0)
>>> Bin(16).list
[1, 0, 0, 0, 0]
>>> Bin(0x4142).bytes
b'AB'
>>> Bin("1101").int
13
>>> Bin("1110001101").hex
'38d'
>>> Bin("1101") == Bin((1, 1, 0, 1)) == Bin([1, 1, 0, 1]) == Bin(13)
True
>>> Bin([0, 1, 2])
Traceback (most recent call last):
ValueError: integer 2 is not binary
property hw

Alias for weight.

property wt

Alias for weight.

n
int
classmethod empty(n=0)[source]

Create empty Bin.

>>> Bin.empty(0)
Bin(0b0, n=0)
>>> Bin.empty(4)
Bin(0b0000, n=4)
>>> Bin.zero(4)
Bin(0b0000, n=4)
classmethod zero(n=0)

Create empty Bin.

>>> Bin.empty(0)
Bin(0b0, n=0)
>>> Bin.empty(4)
Bin(0b0000, n=4)
>>> Bin.zero(4)
Bin(0b0000, n=4)
classmethod full(n)[source]

Create full Bin of width n.

>>> Bin.full(0)
Bin(0b0, n=0)
>>> Bin.full(4)
Bin(0b1111, n=4)
>>> Bin.ones(4)
Bin(0b1111, n=4)
classmethod ones(n)

Create full Bin of width n.

>>> Bin.full(0)
Bin(0b0, n=0)
>>> Bin.full(4)
Bin(0b1111, n=4)
>>> Bin.ones(4)
Bin(0b1111, n=4)
classmethod iter(*ns)[source]

Iterate over all n-bit Bin`s. Multiple arguments yield product of single iters, i.e., all tuples of :class:`Bin`s of given sizes `ns.

>>> list(Bin.iter(2))
[Bin(0b00, n=2), Bin(0b01, n=2), Bin(0b10, n=2), Bin(0b11, n=2)]
>>> pprint(list(Bin.iter(1, 2)))
[(Bin(0b0, n=1), Bin(0b00, n=2)),
 (Bin(0b0, n=1), Bin(0b01, n=2)),
 (Bin(0b0, n=1), Bin(0b10, n=2)),
 (Bin(0b0, n=1), Bin(0b11, n=2)),
 (Bin(0b1, n=1), Bin(0b00, n=2)),
 (Bin(0b1, n=1), Bin(0b01, n=2)),
 (Bin(0b1, n=1), Bin(0b10, n=2)),
 (Bin(0b1, n=1), Bin(0b11, n=2))]
classmethod unit(i, n)[source]

Bin integer only with bit at index i set (equals \(2^{n-1-(i\mod n)}\))

Parameters
  • i (int) – The index, requires \(-n \le i < n\).

  • n (int) – The width.

Examples

>>> Bin.unit(0, 5)
Bin(0b10000, n=5)
>>> Bin.unit(3, 5)
Bin(0b00010, n=5)
>>> Bin.unit(4, 5)
Bin(0b00001, n=5)
>>> Bin.unit(-5, 5)
Bin(0b10000, n=5)
>>> Bin.unit(-1, 5)
Bin(0b00001, n=5)
>>> Bin.unit(5, 5)
Traceback (most recent call last):
ValueError: integer out of range
>>> Bin.unit(-6, 5)
Traceback (most recent call last):
ValueError: integer out of range
classmethod random(n, nonzero=False)[source]

Random n-bit Bin.

Parameters
  • n (int) – The width.

  • nonzero (bool = False) – Force nonzero integer?

Examples

>>> Bin.random(0)
Bin(0b0, n=0)
>>> Bin.random(10)  
Bin(0b0110110011, n=10)
>>> Bin.random(10)  
Bin(0b1010000111, n=10)
>>> all(Bin.random(3) for _ in range(1000))
False
>>> all(Bin.random(3, nonzero=True) for _ in range(1000))
True
property mask

Binary mask for the full width.

Type

Bin

copy()[source]
classmethod array(*args, n=None, ns=None)[source]

Convert a list of objects to a list of Bin with the same n, or an iterable ns of sizes.

>>> Bin.array(1, 2, 3, 4, n=4)
[Bin(0b0001, n=4), Bin(0b0010, n=4), Bin(0b0011, n=4), Bin(0b0100, n=4)]
>>> Bin.array(1, 2, 3, 4, ns=(1,2,3,4))
[Bin(0b1, n=1), Bin(0b10, n=2), Bin(0b011, n=3), Bin(0b0100, n=4)]
>>> Bin.concat(*Bin.array(1, 2, 3, 4, n=4)).hex
'1234'
>>> Bin.concat(*Bin.array(1, 2, 3, 4, ns=(4, 8, 4, 16))).hex
'10230004'
resize(n, truncate=False)[source]

Change the width of the integer (truncate must be set to True to force truncation, otherwise an Exceptino will be raised if doesn’t fit).

Examples

>>> Bin(3).resize(10)
Bin(0b0000000011, n=10)
>>> Bin(3).resize(1)
Traceback (most recent call last):
ValueError: integer out of range
>>> Bin(3).resize(1, truncate=True)
Bin(0b1, n=1)
property tuple

Tuple of the binary representation.

Examples

>>> Bin(0x123).tuple
(1, 0, 0, 1, 0, 0, 0, 1, 1)
>>> Bin(0x123, 10).tuple
(0, 1, 0, 0, 1, 0, 0, 0, 1, 1)
property list

List of the binary representation.

Examples

>>> Bin(0x123).list
[1, 0, 0, 1, 0, 0, 0, 1, 1]
>>> Bin(0x123, 10).list
[0, 1, 0, 0, 1, 0, 0, 0, 1, 1]
property vector

GF(2)-vector of the binary representation.

property support

Tuple of indices i such that bits with index i is set.

>>> Bin(0x1234, 16).support
(3, 6, 10, 11, 13)
>>> Bin(0x1234).support
(0, 3, 7, 8, 10)
property str

01-string binary representation.

property bytes

Bytes representation (big-endian).

>>> Bin(0x4142, 24).bytes
b'\x00AB'
property hex

Hexadecimal representation.

>>> Bin(0xabc, 12).hex
'abc'
>>> Bin(0xabc, 13).hex
'0abc'
>>> Bin(0xabc, 16).hex
'0abc'
property bin
>>> Bin(0xabc, 12).bin
'101010111100'
>>> Bin(0xabc, 13).bin
'0101010111100'
>>> Bin(0xabc, 16).bin
'0000101010111100'
is_prec(other)[source]
is_preceq(other)[source]
is_succ(other)[source]
is_succeq(other)[source]
property weight

Hamming weight. (Aliases: hw, wt).

>>> Bin(0).weight
0
>>> Bin(1).weight
1
>>> Bin(0xffffffff).weight
32
>>> Bin(2**64-1).weight
64
>>> Bin(int("10" * 999, 2)).weight
999
property parity

Parity of all bits.

>>> Bin(0).parity
0
>>> Bin(1).parity
1
>>> Bin(4).parity
1
>>> Bin(6).parity
0
>>> Bin(2**100).parity
1
>>> Bin(2**100 + 1).parity
0
>>> Bin(2**100 ^ 7).parity
0
>>> Bin(2**100 ^ 3).parity
1
rol(n)[source]

Rotate left by @n bits

>>> hex( Bin(0x1234, 16).rol(4).int )
'0x2341'
>>> hex( Bin(0x1234, 16).rol(12).int )
'0x4123'
ror(n)[source]

Rotate right by @n bits

>>> hex( Bin(0x1234, 16).ror(4).int )
'0x4123'
>>> hex( Bin(0x1234, 16).ror(12).int )
'0x2341'
>>> Bin(1, 16).rol(1).n
16
scalar_bin(other)[source]

Dot product in GF(2).

>>> Bin(0).scalar_bin(0)
0
>>> Bin(1).scalar_bin(1)
1
>>> Bin(0xf731).scalar_bin(0xffffff)
0
>>> Bin(1).scalar_bin(3)
1
>>> Bin(7).scalar_bin(15)
1

Same as:

>>> (Bin(7) @ 15) & 1
1
>>> (Bin(7) & 15).parity
1
scalar_int(other)[source]

Dot product in integers. Aliased as overloaded @, similarly to .dot = @ in numpy.

>>> Bin(0) @ 0
0
>>> Bin(1) @ 1
1
>>> Bin(0xf731) @ 0xffffff
10
>>> Bin(1) @ 3
1
>>> Bin(7) @ 15
3

Same as:

>>> (Bin(7) & 15).weight
3
bit_product(mask)[source]

Multiply bits selected by mask. (better method name?)

>>> Bin("101").bit_product("101")
1
>>> Bin("101").bit_product("100")
1
>>> Bin("101").bit_product("001")
1
>>> Bin("101").bit_product("111")
0
>>> Bin("1111").bit_product("1111")
1
>>> Bin("1111").bit_product("1110")
1
>>> Bin("1111").bit_product("0111")
1
>>> Bin("0111").bit_product("1111")
0
>>> Bin("1110").bit_product("1111")
0
classmethod concat(*args, n=None, ns=None)[source]

Concatenate bitstrings. Classmethod, varargs. :param:

>>> Bin.concat(Bin(128), Bin(255), Bin(1, n=8)).str
'100000001111111100000001'
>>> Bin.concat(1, 2, 3, 4).str
'11011100'
>>> Bin.concat(1, 2, 3, 4, n=3).str
'001010011100'
>>> Bin.concat(1, 2, 3, 15, n=4).str
'0001001000111111'
>>> Bin.concat(1, 2, 3, 16, n=4).str
Traceback (most recent call last):
ValueError: integer out of range
halves()[source]
>>> Bin(0x79, 8).halves()
(Bin(0b0111, n=4), Bin(0b1001, n=4))
swap_halves()[source]
>>> Bin(0x79, 8).swap_halves().hex
'97'
split(parts=None, n=None, ns=None)[source]

Split the bitstring into several parts. Either: - into @parts same-sized chunks - into parts with sizes @n each or given by @ns

>>> Bin(0x123, 12).split(3) == Bin(0x123, 12).split(parts=3)
True
>>> Bin(0x123, 12).split(parts=3)
(Bin(0b0001, n=4), Bin(0b0010, n=4), Bin(0b0011, n=4))
>>> Bin(0x9821, 16).split(ns=(4, 4, 8))   # 0x21 == 33
(Bin(0b1001, n=4), Bin(0b1000, n=4), Bin(0b00100001, n=8))
>>> Bin(0x9821, 16).split(n=4)
(Bin(0b1001, n=4), Bin(0b1000, n=4), Bin(0b0010, n=4), Bin(0b0001, n=4))
squeeze_by_mask(mask)[source]

Keep bits selected by mask and delete the others.

Parameters

mask (Bin or int or str) – Mask for squeeze, will be converted to Bin(..., self.n)

Examples

>>> Bin("10101").squeeze_by_mask("10101").str
'111'
>>> Bin("10101").squeeze_by_mask("01111").str
'0101'

Fixed-width aliases

binteger.Bin8(x)[source]

Fixed-width 8-bit Bin (shortcut to Bin(x, 8)) .

binteger.Bin16(x)[source]

Fixed-width 16-bit Bin (shortcut to Bin(x, 16)) .

binteger.Bin32(x)[source]

Fixed-width 32-bit Bin (shortcut to Bin(x, 32)) .

binteger.Bin64(x)[source]

Fixed-width 64-bit Bin (shortcut to Bin(x, 64)) .