Module bits
source code
Storage of binary values of arbitrary length.
Endianness is an issue here because we want to naturally "do the right
thing" and unfortunately this varies, depending on context. Most target
hardware (x86) is little-endian, but network protocols are typically
big-endian.
I personally prefer big-endian for long hex strings - it seems obvious that
0x123456 should be encoded as [0x12, 0x34, 0x56]. On the other hand, it
also seems reasonable that the integer 1193046 (=0x123456) should be stored
small-endian as [0x56, 0x34, 0x12, 0x00] because that is how it is
stored in memory. Unfortunately we cannot implement both because integer
values do not contain any flag to say how the user specified them (hex or
decimal).
A very similar issue - that integers do not carry any information to say
how many leading zeroes were entered by the user - suggests a solution to
this problem. To solve the leading zeroes issue we accept integers as
strings and do the conversion ourselves. Since we are dealing with strings
we can invent an entirely new encoding to specify endianness. We will use
little-endian for ints and the "usual" notation since this reflects the
hardware (it appeals to the idea that we are simply taking the chunk of
memory in which the integer existed and using it directly). For big endian,
we will use a trailing type flag (ie change "ends") in strings.
So 1193046, "1193046", 0x123456, "0x123456" all encode to [0x56, 0x34, 0x12]
(module some questions about implicit/explicit lengths).
But "123456x0" encodes to [0x12, 0x34, 0x56]. This does have a slight
wrinkle - 100b0 looks like a hex value (but is not, as it does not start
with 0x).
Note: No attempt is made to handle sign (complements etc).
|
|
Int
An integer with a length (the number of bits).
|
|
|
BitString
A sequence of bits, of arbitrary length.
|
|
|
BitIterator
A sequence of bits (used by BitString).
|
|
|
ByteIterator
A sequence of bytes (used by BitString).
|
|
|
swap_table()
Table of reversed bit patterns for 8 bits. |
source code
|
|
|
|
unpack_length(length)
Length is in bits, unless a decimal is specified, in which case it
it has the structure bytes.bits. |
source code
|
|
|
|
bytes_for_bits(bits,
offset=0)
The number of bytes required to specify the given number of bits. |
source code
|
|
|
|
STRICT = 'strict'
|
|
|
ONE = BitString(b '\x01', 1)
|
|
|
ZERO = BitString(b '\x00', 1)
|
Length is in bits, unless a decimal is specified, in which case it
it has the structure bytes.bits. Obviously this is ambiguous with float
values (eg 3.1 or 3.10), but since we only care about bits 0-7 we can
avoid any issues by requiring that range.
|