Last active
June 26, 2018 14:10
-
-
Save bsolomon1124/da87640fb411f6e273f2dca82b90c71a to your computer and use it in GitHub Desktop.
Demonstration of `int.from_bytes()`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Demonstration of how `int.from_bytes()` converts a Python bytes obj to int. | |
| # Used in random module's `SystemRandom.random()` to generate a float in [0.0, 1.0) from `os.urandom()` | |
| # https://github.com/python/cpython/blob/c6040638aa1537709add895d24cdbbb9ee310fde/Lib/random.py#L676 | |
| # | |
| # An example: the number 1984 can be "decomposed" in the decimal system (base 10) | |
| # as (1 * 10 ** 3) | |
| # + (9 * 10 ** 2) | |
| # + (8 * 10 ** 1) | |
| # + (4 * 10 ** 0) | |
| # | |
| # `int.from_bytes()` (with big endianness) uses a base-256 numbering system | |
| # Given b = b'\xe6\x04\x00\x00', | |
| # >>> list(b) | |
| # [230, 4, 0, 0] | |
| # And the int is then | |
| # (230 * 256 ** 3) | |
| # + (4 * 256 ** 2) | |
| # + (0 * 256 ** 1) | |
| # + (0 * 256 ** 0) == 3859021824 | |
| def bytes_to_int(b: bytes, byteorder: str='big') -> int: | |
| if byteorder == 'big': | |
| return sum(j * 256 ** i for i, j in enumerate(b[::-1])) | |
| elif byteorder == 'little': | |
| return sum(j * 256 ** i for i, j in enumerate(b)) | |
| else: | |
| raise ValueError("byteorder must be either 'little' or 'big'.") | |
| def test(seed=None): | |
| for _ in range(10): | |
| b = os.urandom(random.randint(0, 100)) | |
| assert bytes_to_int(b, 'big') == int.from_bytes(b, 'big'), b | |
| assert bytes_to_int(b, 'little') == int.from_bytes(b, 'little'), b | |
| if __name__ == '__main__' | |
| import os | |
| import random | |
| import sys | |
| sys.exit(test()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment