Skip to content

Instantly share code, notes, and snippets.

@bsolomon1124
Last active June 26, 2018 14:10
Show Gist options
  • Select an option

  • Save bsolomon1124/da87640fb411f6e273f2dca82b90c71a to your computer and use it in GitHub Desktop.

Select an option

Save bsolomon1124/da87640fb411f6e273f2dca82b90c71a to your computer and use it in GitHub Desktop.
Demonstration of `int.from_bytes()`
# 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