MutableBits¶
The MutableBits class is the mutable version of Bits.
It has almost all of the methods and properties of Bits and adds capabilities for changing the bits in-place.
The new methods are:
Some methods from Bits that return a generator are not allowed as the underlying binary value could change
while the generator is still live. For example the Bits.find_all method is not available on MutableBits, but you can use
.to_bits().find_all() instead.
You can switch between MutableBits and Bits using the MutableBits.to_bits and Bits.to_mutable_bits methods.f
The reserve and capacity methods can be used to manage the capacity of the MutableBits to avoid unneccesary reallocations, but their use is purely for performance optimization.
- class MutableBits(s=None)¶
A mutable container of binary data.
To construct, use a builder ‘from’ method:
MutableBits.from_bytes(b)- Create directly from abytesobject.MutableBits.from_string(s)- Use a formatted string.MutableBits.from_bools(i)- Convert each element inito a bool.MutableBits.from_zeros(length)- Initialise withlength‘0’ bits.MutableBits.from_ones(length)- Initialise withlength‘1’ bits.MutableBits.from_random(length, [seed])- Initialise withlengthpseudo-randomly set bits.MutableBits.from_dtype(dtype, value)- Combine a data type with a value.MutableBits.from_joined(iterable)- Concatenate an iterable of objects.
Using the constructor
MutableBits(s)is an alias forMutableBits.from_string(s).- all()¶
Return True if all bits are equal to 1, otherwise return False.
- Returns:
Trueif all bits are 1, otherwiseFalse.
>>> MutableBits('0b1111').all() True >>> MutableBits('0b1011').all() False
- any()¶
Return True if any bits are equal to 1, otherwise return False.
- Returns:
Trueif any bits are 1, otherwiseFalse.
>>> MutableBits('0b0000').any() False >>> MutableBits('0b1000').any() True
- append(bs)¶
Append bits to the end of the current MutableBits in-place.
- Parameters:
bs – The bits to append.
- Returns:
self
>>> a = MutableBits('0x0f') >>> a.append('0x0a') MutableBits('0x0f0a')
- as_bits()¶
Create and return a Bits instance by moving the MutableBits data.
The data is moved to the new Bits, so this MutableBits will be empty after the operation. This is more efficient than
to_bitsif you no longer need the MutableBits.It will try to reclaim any excess memory capacity that the MutableBits may have had.
- Returns:
A Bits instance with the same bit data.
>>> a = MutableBits('0b1011') >>> b = a.as_bits() >>> a MutableBits() >>> b Bits('0b1101')
- byte_swap(byte_length=None)¶
Change the byte endianness in-place. Returns self.
The whole of the MutableBits will be byte-swapped. It must be a multiple of byte_length long.
- Parameters:
byte_length – An int giving the number of bytes in each swap.
- Returns:
self
>>> a = MutableBits('0x12345678') >>> a.byte_swap(2) MutableBits('0x34127856')
- capacity()¶
Return the number of bits the MutableBits can hold without reallocating memory.
The capacity is always equal to or greater than the current length of the MutableBits. If the length ever exceeds the capacity then memory will have to be reallocated, and the capacity will increase.
It can be helpful as a performance optimization to reserve enough capacity before constructing a large MutableBits incrementally. See also
reserve.
- clear()¶
Clear all bits, making the MutableBits empty.
This doesn’t change the allocated capacity, so won’t free up any memory.
- count(value)¶
Count of total number of either zero or one bits.
- Parameters:
value – If bool(value) is True, bits set to 1 are counted; otherwise, bits set to 0 are counted.
- Returns:
The count of bits set to 1 or 0.
>>> MutableBits('0xef').count(1) 7
- ends_with(suffix)¶
Return whether the current MutableBits ends with suffix.
- Parameters:
suffix – The Bits to search for.
- Returns:
True if the Bits ends with the suffix, otherwise False.
>>> MutableBits('0b101100').ends_with('0b10-') True >>> MutableBits('0b101100').ends_with('0b101') False
- find(bs, /, start=None, end=None, byte_aligned=None)¶
Find first occurrence of substring bs.
Returns the bit position if found, or None if not found.
- Parameters:
bs (
Union[Bits,MutableBits,str,bytearray,bytes,memoryview]) – The Bits to find.start (
int|None) – The starting bit position. Defaults to 0.end (
int|None) – The end position. Defaults to len(self).byte_aligned (
bool|None) – IfTrue, the Bits will only be found on byte boundaries.
- Return type:
int|None- Returns:
The bit position if found, or None if not found.
>>> Bits.from_string('0xc3e').find('0b1111') 6
- from_bools()¶
Create a new instance from an iterable by converting each element to a bool.
- Parameters:
i – The iterable to convert to a
MutableBits.
a = MutableBits.from_bools([False, 0, 1, "Steven"]) # binary 0011
- from_bytes()¶
Create a new instance from a bytes object.
- Parameters:
b – The bytes object to convert to a
MutableBits.
a = MutableBits.from_bytes(b"some_bytes_maybe_from_a_file")
- classmethod from_dtype(dtype, value, /)¶
Pack a value according to a data type or data type tuple.
- Parameters:
dtype (
Dtype|str) – The data type to pack.value (
Any) – A value appropriate for the data type.
- Return type:
- Returns:
A newly constructed
MutableBits.
a = MutableBits.from_dtype("u8", 17) b = MutableBits.from_dtype("f16, i4, bool", [2.25, -3, False])
- from_joined()¶
Create a new instance by concatenating a sequence of Bits objects.
This method concatenates a sequence of Bits objects into a single MutableBits object.
- Parameters:
sequence – A sequence to concatenate. Items can either be a Bits object, or a string or bytes-like object that could create one via the
from_stringorfrom_bytesmethods.
a = MutableBits.from_joined([f'u6={x}' for x in range(64)]) b = MutableBits.from_joined(['0x01', 'i4 = -1', b'some_bytes'])
- from_ones()¶
Create a new instance with all bits set to one.
- Parameters:
length – The number of bits to set.
>>> MutableBits.from_ones(5) MutableBits('0b11111')
- from_random(seed=None)¶
Create a new instance with all bits pseudo-randomly set.
- Parameters:
length – The number of bits to set. Must be positive.
seed – An optional seed as a bytes or bytearray.
- Returns:
A newly constructed
MutableBitswith random data.
Note that this uses a pseudo-random number generator and so might not suitable for cryptographic or other more serious purposes.
a = MutableBits.from_random(1000000) # A million random bits b = MutableBits.from_random(100, b'a_seed')
- from_string()¶
Create a new instance from a formatted string.
This method initializes a new instance of
MutableBitsusing a formatted string.- Parameters:
s – The formatted string to convert.
- Returns:
A newly constructed
MutableBits.
a = MutableBits.from_string("0xff01") b = MutableBits.from_string("0b1") c = MutableBits.from_string("u12 = 31, f16=-0.25")
The __init__ method for MutableBits redirects to the from_string method and is sometimes more convenient:
a = MutableBits("0xff01") # MutableBits(s) is equivalent to MutableBits.from_string(s)
- from_zeros()¶
Create a new instance with all bits set to zero.
- Parameters:
length – The number of bits to set.
- Returns:
A MutableBits object with all bits set to zero.
a = MutableBits.from_zeros(500) # 500 zero bits
- info()¶
Return a descriptive string with information about the Bits.
Note that the output is designed to be helpful to users and is not considered part of the API. You should not use the output programmatically as it may change even between point versions.
>>> Bits('0b1101').info() '4 bits: binary = 1101, hex = d, unsigned int = 13, signed int = -3'
- Return type:
str
- insert(pos, bs)¶
Inserts another Bits or MutableBits at bit position pos. Returns self.
- Parameters:
pos – The bit position to insert at.
bs – The Bits to insert.
- Returns:
self
Raises ValueError if pos < 0 or pos > len(self).
>>> a = MutableBits('0b1011') >>> a.insert(2, '0b00') MutableBits('0b100011')
- invert(pos=None)¶
Return the MutableBits with one or many bits inverted between 0 and 1.
- Parameters:
pos – Either a single bit position or an iterable of bit positions.
- Returns:
self
Raises IndexError if pos < -len(self) or pos >= len(self).
>>> a = MutableBits('0b10111') >>> a.invert(1) MutableBits('0b11111') >>> a.invert([0, 2]) MutableBits('0b01011') >>> a.invert() MutableBits('0b10100')
- pp(dtype1=None, dtype2=None, groups=None, width=80, show_offset=True, stream=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)¶
Pretty print the Bits’s value.
- Parameters:
dtype1 (
str|Dtype|None) – First data type to display.dtype2 (
str|Dtype|None) – Optional second data type.groups (
int|None) – How many groups of bits to display on each line. This overrides any value given for width.width (
int) – Max width of printed lines. Defaults to 80, but ignored if groups parameter is set. A single group will always be printed per line even if it exceeds the max width.show_offset (
bool) – If True (the default) shows the bit offset in the first column of each line.stream (
TextIO) – A TextIO object with a write() method. Defaults to sys.stdout.
- Return type:
None
s.pp('hex4', groups=6) s.pp('bin', 'hex', show_offset=False)
- prepend(bs)¶
Prepend bits to the beginning of the current MutableBits in-place.
- Parameters:
bs – The bits to prepend.
- Returns:
self
>>> a = MutableBits('0x0f') >>> a.prepend('0x0a') MutableBits('0x0a0f')
- replace(old, new, /, start=None, end=None, count=None, byte_aligned=None)¶
Replaces all occurrences of old with new. Returns self.
- Parameters:
old (
Union[Bits,MutableBits,str,bytearray,bytes,memoryview]) – The Bits or to replace.new (
Union[Bits,MutableBits,str,bytearray,bytes,memoryview]) – The replacement Bits.start (
int|None) – Any occurrences that start before this bit position will not be replaced.end (
int|None) – Any occurrences that finish after this bit position will not be replaced.count (
int|None) – The maximum number of replacements to make. Defaults to all.byte_aligned (
bool|None) – If True, replacements will only be made on byte boundaries.
- Return type:
- Returns:
self
- Raises:
ValueError – if old is empty or if start or end are out of range.
>>> s = MutableBits('0b10011') >>> s.replace('0b1', '0xf') MutableBits('0b11110011111111')
- reserve(additional)¶
Reserve memory for at least additional more bits to be appended to the MutableBits.
This can be helpful as a performance optimization to avoid multiple memory reallocations when constructing a large MutableBits incrementally. If enough memory is already reserved then this method will have no effect. See also
capacity.- Parameters:
additional – The number of bits that can be appended without any further memory reallocations.
- reverse()¶
Reverse bits in-place.
- Returns:
self
>>> a = MutableBits('0b1011') >>> a.reverse() MutableBits('0b1101')
- rfind(bs, /, start=None, end=None, byte_aligned=None)¶
Find final occurrence of substring bs.
Returns the bit position if found, or None if not found. Note that start and end define a slice in the usual way, so the occurrence of bs closest to the end posistion will be found.
- Parameters:
bs (
Union[Bits,MutableBits,str,bytearray,bytes,memoryview]) – The Bits to find.start (
int|None) – The starting bit position of the slice to search. Defaults to 0.end (
int|None) – The end bit position of the slice to search. Defaults to len(self).byte_aligned (
bool|None) – If True, the Bits will only be found on byte boundaries.
- Return type:
int|None- Returns:
The bit position if found, or None if not found.
Raises ValueError if bs is empty.
>>> Bits('0b110110').rfind('0b1') 4 >>> Bits('0b110110').rfind('0b0') 5
- rol(n, start=None, end=None)¶
Rotates bit pattern to the left. Returns self.
- Parameters:
n – The number of bits to rotate by.
start – Start of slice to rotate. Defaults to 0.
end – End of slice to rotate. Defaults to len(self).
- Returns:
self
Raises ValueError if n < 0.
>>> a = MutableBits('0b1011') >>> a.rol(2) MutableBits('0b1110')
- ror(n, start=None, end=None)¶
Rotates bit pattern to the right. Returns self.
- Parameters:
n – The number of bits to rotate by.
start – Start of slice to rotate. Defaults to 0.
end – End of slice to rotate. Defaults to len(self).
- Returns:
self
Raises ValueError if n < 0.
>>> a = MutableBits('0b1011') >>> a.ror(1) MutableBits('0b1101')
- set(value, pos)¶
Set one or many bits set to 1 or 0. Returns self.
- Parameters:
value – If bool(value) is True, bits are set to 1, otherwise they are set to 0.
pos – Either a single bit position or an iterable of bit positions.
- Returns:
self
- Raises:
IndexError – if pos < -len(self) or pos >= len(self).
>>> a = MutableBits.from_zeros(10) >>> a.set(1, 5) MutableBits('0b0000010000') >>> a.set(1, [-1, -2]) MutableBits('0b0000010011') >>> a.set(0, range(8, 10)) MutableBits('0b0000010000')
- starts_with(prefix)¶
Return whether the current MutableBits starts with prefix.
- Parameters:
prefix – The Bits to search for.
- Returns:
True if the Bits starts with the prefix, otherwise False.
>>> MutableBits('0b101100').starts_with('0b101') True >>> MutableBits('0b101100').starts_with('0b100') False
- to_bits()¶
Create and return a Bits instance from a copy of the MutableBits data.
This copies the underlying binary data, giving a new independent Bits object. If you no longer need the MutableBits, consider using
as_bitsinstead to avoid the copy.- Returns:
A new Bits instance with the same bit data.
>>> a = MutableBits('0b1011') >>> b = a.to_bits() >>> a MutableBits('0b1011') >>> b Bits('0b1101')
- to_bytes()¶
Return the MutableBits as bytes, padding with zero bits if needed.
Up to seven zero bits will be added at the end to byte align.
- Returns:
The MutableBits as bytes.
- unpack(dtype, /, start=None, end=None)¶
Interpret the Bits as a given data type or list of data types.
If a single Dtype is given then a single value will be returned, otherwise a list of values will be returned. A single Dtype with no length can be used to interpret the whole Bits - in this common case properties are provided as a shortcut. For example instead of
b.unpack('bin')you can useb.bin.- Parameters:
- Return type:
Any|list[Any]- Returns:
The interpreted value(s).
>>> s = Bits('0xdeadbeef') >>> s.unpack(['bin4', 'u28']) ['1101', 246267631] >>> s.unpack(['f16', '[u4; 4]']) [-427.25, (11, 14, 14, 15)] >>> s.unpack('i') -559038737 >>> s.i -559038737
- property bin¶
The MutableBits as a binary string. Read and write.
- property bits¶
The MutableBits as a Bits object. Read and write.
- property bool¶
The MutableBits as a bool (True or False). Read and write.
- property bytes¶
The MutableBits as a bytes object. Read and write.
- property f¶
The MutableBits as an IEEE floating point number. Read and write.
- property f_be¶
The MutableBits as an IEEE floating point number in big-endian byte order. Read and write.
- property f_le¶
The MutableBits as an IEEE floating point number in little-endian byte order. Read and write.
- property f_ne¶
The MutableBits as an IEEE floating point number in native-endian (i.e. little-endian-endian) byte order. Read and write.
- property hex¶
The MutableBits as a hexadecimal string. Read and write.
- property i¶
The MutableBits as a two’s complement signed int. Read and write.
- property i_be¶
The MutableBits as a two’s complement signed int in big-endian byte order. Read and write.
- property i_le¶
The MutableBits as a two’s complement signed int in little-endian byte order. Read and write.
- property i_ne¶
The MutableBits as a two’s complement signed int in native-endian (i.e. little-endian-endian) byte order. Read and write.
- property oct¶
The MutableBits as an octal string. Read and write.
- property pad¶
The MutableBits as a skipped section of padding. Read and write.
- property u¶
The MutableBits as a two’s complement unsigned int. Read and write.
- property u_be¶
The MutableBits as a two’s complement unsigned int in big-endian byte order. Read and write.
- property u_le¶
The MutableBits as a two’s complement unsigned int in little-endian byte order. Read and write.
- property u_ne¶
The MutableBits as a two’s complement unsigned int in native-endian (i.e. little-endian-endian) byte order. Read and write.