|
- # Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # https://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
-
- """Data transformation functions.
-
- From bytes to a number, number to bytes, etc.
- """
-
- import math
-
-
- def bytes2int(raw_bytes: bytes) -> int:
- r"""Converts a list of bytes or an 8-bit string to an integer.
-
- When using unicode strings, encode it to some encoding like UTF8 first.
-
- >>> (((128 * 256) + 64) * 256) + 15
- 8405007
- >>> bytes2int(b'\x80@\x0f')
- 8405007
-
- """
- return int.from_bytes(raw_bytes, "big", signed=False)
-
-
- def int2bytes(number: int, fill_size: int = 0) -> bytes:
- """
- Convert an unsigned integer to bytes (big-endian)::
-
- Does not preserve leading zeros if you don't specify a fill size.
-
- :param number:
- Integer value
- :param fill_size:
- If the optional fill size is given the length of the resulting
- byte string is expected to be the fill size and will be padded
- with prefix zero bytes to satisfy that length.
- :returns:
- Raw bytes (base-256 representation).
- :raises:
- ``OverflowError`` when fill_size is given and the number takes up more
- bytes than fit into the block. This requires the ``overflow``
- argument to this function to be set to ``False`` otherwise, no
- error will be raised.
- """
-
- if number < 0:
- raise ValueError("Number must be an unsigned integer: %d" % number)
-
- bytes_required = max(1, math.ceil(number.bit_length() / 8))
-
- if fill_size > 0:
- return number.to_bytes(fill_size, "big")
-
- return number.to_bytes(bytes_required, "big")
-
-
- if __name__ == "__main__":
- import doctest
-
- doctest.testmod()
|