def generate_random_bits(n_bits, rand_func=generate_random_bytes): """ Generates the specified number of random bits as a byte string. For example:: f(x) -> y such that f(16) -> 1111 1111 1111 1111; bytes_to_integer(y) => 65535L f(17) -> 0000 0001 1111 1111 1111 1111; bytes_to_integer(y) => 131071L :param n_bits: Number of random bits. if n is divisible by 8, (n / 8) bytes will be returned. if n is not divisible by 8, ((n / 8) + 1) bytes will be returned and the prefixed offset-byte will have `(n % 8)` number of random bits, (that is, `8 - (n % 8)` high bits will be cleared). The range of the numbers is 0 to (2**n)-1 inclusive. :param rand_func: Random bytes generator function. :returns: Bytes. """ if not builtins.is_integer(n_bits): raise TypeError("unsupported operand type: %r" % type(n_bits).__name__) if n_bits <= 0: raise ValueError("number of bits must be greater than 0.") # Doesn't perform any floating-point operations. quotient, remainder = divmod(n_bits, 8) random_bytes = rand_func(quotient) if remainder: offset = ord(rand_func(1)) >> (8 - remainder) random_bytes = builtins.byte(offset) + random_bytes return random_bytes
def uint_to_bytes_simple(num): """Simple uint to bytes converter.""" assert num >= 0 if num == 0: return ZERO_BYTE byte_array = [] while num: byte_array.append(builtins.byte(num & 0xff)) num >>= 8 return EMPTY_BYTE.join(reversed(byte_array))
def b58decode_bitcoin(encoded, length=None): """ decode v into a string of len bytes """ long_value = 0 for i, c in enumerate(encoded[::-1]): long_value += ALPHABET.find(_chr(c)) * (BASE**i) result = EMPTY_BYTE while long_value >= 256: div, mod = divmod(long_value, 256) result = builtins.byte(mod) + result long_value = div result = builtins.byte(long_value) + result nPad = 0 for c in encoded: if c == ALPHABET[0]: nPad += 1 else: break result = builtins.byte(0) * nPad + result if length is not None and len(result) != length: return None return result
def b58decode_bitcoin(encoded, length=None): """ decode v into a string of len bytes """ long_value = 0 for i, c in enumerate(encoded[::-1]): long_value += ALPHABET.find(_chr(c)) * (BASE ** i) result = EMPTY_BYTE while long_value >= 256: div, mod = divmod(long_value, 256) result = byte(mod) + result long_value = div result = byte(long_value) + result nPad = 0 for c in encoded: if c == ALPHABET[0]: nPad += 1 else: break result = byte(0) * nPad + result if length is not None and len(result) != length: return None return result
def uint_to_bytes_naive(number, block_size=0): """ Naive slow and accurate implementation. Base for all our tests. Converts a number to a string of bytes. :param number: the number to convert :param block_size: the number of bytes to output. If the number encoded to bytes is less than this, the block will be zero-padded. When not given, the returned block is not padded. :raises: ``OverflowError`` when block_size is given and the number takes up more bytes than fit into the block. """ if number < 0: raise ValueError("Negative numbers cannot be used: %d" % number) # Do some bounds checking needed_bytes = builtins.integer_byte_length(number) if block_size > 0: if needed_bytes > block_size: raise OverflowError("Needed %i bytes for number, but block size " "is %i" % (needed_bytes, block_size)) # Convert the number to bytes. if number == 0: raw_bytes = [ZERO_BYTE] else: raw_bytes = [] num = number while num > 0: raw_bytes.insert(0, builtins.byte(num & 0xFF)) num >>= 8 # Pad with zeroes to fill the block if block_size > 0: padding_size = (block_size - needed_bytes) if number == 0: padding_size -= 1 padding = ZERO_BYTE * padding_size else: padding = EMPTY_BYTE return padding + EMPTY_BYTE.join(raw_bytes)
def _b85decode_chunks(encoded, base85_bytes, base85_ords): """ Base-85 decodes. :param encoded: Encoded ASCII string. :param base85_bytes: Character set to use. :param base85_ords: A function to convert a base85 character to its ordinal value. You should not need to use this. :returns: Base-85-decoded raw bytes. """ # We want 5-tuple chunks, so pad with as many base85_ord == 84 characters # as required to satisfy the length. length = len(encoded) num_uint32s, remainder = divmod(length, 5) if remainder: padding_byte = byte(base85_bytes[84]) # 'u' (ASCII85); '~' (RFC1924) padding_size = 5 - remainder encoded += padding_byte * padding_size num_uint32s += 1 length += padding_size else: padding_size = 0 #uint32s = [0] * num_uint32s uint32s = array('I', [0] * num_uint32s) j = 0 chunk = EMPTY_BYTE try: for i in range(0, length, 5): chunk = encoded[i:i + 5] # uint32_value = 0 # for char in chunk: # uint32_value = uint32_value * 85 + _base85_ords[char] # Above loop unrolled: uint32_value = ((((base85_ords[chunk[0]] * 85 + base85_ords[chunk[1]]) * 85 + base85_ords[chunk[2]]) * 85 + base85_ords[chunk[3]]) * 85 + base85_ords[chunk[4]]) # I've left this approach in here to warn you to NOT use it. # This results in a massive amount of calls to byte_ord inside # tight loops. # uint32_value = ((((base85_ords[byte_ord(chunk[0])] * # 85 + base85_ords[byte_ord(chunk[1])]) * # 85 + base85_ords[byte_ord(chunk[2])]) * # 85 + base85_ords[byte_ord(chunk[3])]) * # 85 + base85_ords[byte_ord(chunk[4])]) # Groups of characters that decode to a value greater than 2**32 − 1 # (encoded as "s8W-!") will cause a decoding error. Bad byte? if uint32_value > UINT32_MAX: # 2**32 - 1 raise OverflowError("Cannot decode chunk `%r`" % chunk) uint32s[j] = uint32_value j += 1 except KeyError: raise OverflowError("Cannot decode chunk `%r`" % chunk) raw_bytes = pack(">" + "L" * num_uint32s, *uint32s) if padding_size: # Only as much padding added before decoding is removed after decoding. raw_bytes = raw_bytes[:-padding_size] return raw_bytes
# I've left this approach in here to warn you to NOT use it. # This results in a massive amount of calls to byte_ord inside # tight loops. Don't use the array. Use the dictionary. It # removes the need to convert to ords at runtime. #RFC1924_ORDS = array('B', [255] * 128) #for ordinal, _byte in enumerate(RFC1924_BYTES): # RFC1924_ORDS[_byte] = ordinal if HAVE_PYTHON3: # pragma: no cover # Python 3 bytes when indexed yield integers, not single-character # byte strings. ASCII85_ORDS = dict((x, x - 33) for x in ASCII85_BYTES) RFC1924_ORDS = dict((x, i) for i, x in enumerate(RFC1924_BYTES)) else: # Indexing into Python 2 bytes yields single-character byte strings. ASCII85_ORDS = dict((byte(x), x - 33) for x in ASCII85_BYTES) RFC1924_ORDS = dict((byte(x), i) for i, x in enumerate(RFC1924_BYTES)) # Pre-computed powers (array index) of 85 used to unroll encoding loops # Therefore, 85**i is equivalent to POW_85[i] for index 0 through 19 # (inclusive). # #POW_85 = tuple(85**power for power in range(20)) POW_85 = ( 1, 85, 7225, 614125, 52200625, 4437053125,
from mom import builtins from mom import string from mom.codec import _base __author__ = "[email protected] (Yesudeep Mangalapilly)" EMPTY_BYTE = _compat.EMPTY_BYTE # Follows ASCII order. ASCII36_BYTES = (string.DIGITS + string.ASCII_UPPERCASE).encode("ascii") # Therefore, b"1" represents b"\0". if _compat.HAVE_PYTHON3: ASCII36_BYTES = tuple(builtins.byte(x) for x in ASCII36_BYTES) def b36encode(raw_bytes, base_bytes=ASCII36_BYTES, _padding=True): """ Base-36 encodes a sequence of raw bytes. Zero-byte sequences are preserved by default. :param raw_bytes: Raw bytes to encode. :param base_bytes: The character set to use. Defaults to ``ASCII36_BYTES`` that uses natural ASCII order. :param _padding: (Internal) ``True`` (default) to include prefixed zero-byte sequence padding converted to appropriate representation.
except ImportError: #pragma: no cover psyco = None # pylint: enable-msg=R0801 from mom import string from mom._compat import HAVE_PYTHON3, EMPTY_BYTE from mom.builtins import byte from mom.codec._base import base_encode, uint_to_base256 # Follows ASCII order. ASCII36_BYTES = (string.DIGITS + string.ASCII_UPPERCASE).encode("ascii") # Therefore, b'1' represents b'\0'. if HAVE_PYTHON3: ASCII36_BYTES = tuple(byte(x) for x in ASCII36_BYTES) def b36encode(raw_bytes, base_bytes=ASCII36_BYTES, _padding=True): """ Base-36 encodes a sequence of raw bytes. Zero-byte sequences are preserved by default. :param raw_bytes: Raw bytes to encode. :param base_bytes: The character set to use. Defaults to ``ASCII36_BYTES`` that uses natural ASCII order. :param _padding: (Internal) ``True`` (default) to include prefixed zero-byte sequence padding converted to appropriate representation.
def _chr(c): return builtins.byte(c)
def test_byte(self): for i in range(256): byt = byte(i) self.assertTrue(is_bytes(byt)) self.assertEqual(ord(byt), i)
ASCII58_ORDS = dict((x, i) for i, x in enumerate(ASCII58_BYTES)) # Really, I don't understand why people use the non-ASCII order, # but if you really like it that much, go ahead. Be my guest. Here # is what you will need: # # Does not follow ASCII order. ALT58_BYTES = ("123456789" "abcdefghijkmnopqrstuvwxyz" "ABCDEFGHJKLMNPQRSTUVWXYZ").encode("ascii") # Therefore, b"1" represents b"\0". ALT58_ORDS = dict((x, i) for i, x in enumerate(ALT58_BYTES)) if _compat.HAVE_PYTHON3: ASCII58_BYTES = tuple(builtins.byte(x) for x in ASCII58_BYTES) ALT58_BYTES = tuple(builtins.byte(x) for x in ALT58_BYTES) # If you're going to make people type stuff longer than this length # I don't know what to tell you. Beyond this length powers # are computed, so be careful if you care about computation speed. # I think this is a VERY generous range. Decoding bytes fewer than 512 # will use this pre-computed lookup table, and hence, be faster. POW_58 = tuple(58 ** power for power in builtins.range(512)) def b58encode(raw_bytes, base_bytes=ASCII58_BYTES, _padding=True): """ Base58 encodes a sequence of raw bytes. Zero-byte sequences are preserved by default.
# I've left this approach in here to warn you to NOT use it. # This results in a massive amount of calls to byte_ord inside # tight loops. Don't use the array. Use the dictionary. It # removes the need to convert to ords at runtime. # RFC1924_ORDS = array.array("B", [255] * 128) # for ordinal, _byte in enumerate(RFC1924_BYTES): # RFC1924_ORDS[_byte] = ordinal if _compat.HAVE_PYTHON3: # pragma: no cover # Python 3 bytes when indexed yield integers, not single-character # byte strings. ASCII85_ORDS = dict((x, x - 33) for x in ASCII85_BYTES) RFC1924_ORDS = dict((x, i) for i, x in enumerate(RFC1924_BYTES)) else: # Indexing into Python 2 bytes yields single-character byte strings. ASCII85_ORDS = dict((builtins.byte(x), x - 33) for x in ASCII85_BYTES) RFC1924_ORDS = dict((builtins.byte(x), i) for i, x in enumerate(RFC1924_BYTES)) # Pre-computed powers (array index) of 85 used to unroll encoding loops # Therefore, 85**i is equivalent to POW_85[i] for index 0 through 19 # (inclusive). # #POW_85 = tuple(85**power for power in builtins.range(20)) POW_85 = ( 1, 85, 7225, 614125, 52200625,
# Therefore, b"1" represents b"\0". ASCII58_ORDS = dict((x, i) for i, x in enumerate(ASCII58_BYTES)) # Really, I don't understand why people use the non-ASCII order, # but if you really like it that much, go ahead. Be my guest. Here # is what you will need: # # Does not follow ASCII order. ALT58_BYTES = ("123456789" "abcdefghijkmnopqrstuvwxyz" "ABCDEFGHJKLMNPQRSTUVWXYZ").encode("ascii") # Therefore, b"1" represents b"\0". ALT58_ORDS = dict((x, i) for i, x in enumerate(ALT58_BYTES)) if _compat.HAVE_PYTHON3: ASCII58_BYTES = tuple(builtins.byte(x) for x in ASCII58_BYTES) ALT58_BYTES = tuple(builtins.byte(x) for x in ALT58_BYTES) # If you're going to make people type stuff longer than this length # I don't know what to tell you. Beyond this length powers # are computed, so be careful if you care about computation speed. # I think this is a VERY generous range. Decoding bytes fewer than 512 # will use this pre-computed lookup table, and hence, be faster. POW_58 = tuple(58**power for power in builtins.range(512)) def b58encode(raw_bytes, base_bytes=ASCII58_BYTES, _padding=True): """ Base58 encodes a sequence of raw bytes. Zero-byte sequences are preserved by default.
ASCII62_ORDS = dict((x, i) for i, x in enumerate(ASCII62_BYTES)) # Really, I don't understand why people use the non-ASCII order, # but if you really like it that much, go ahead. Be my guest. Here # is what you will need: # # Does not follow ASCII order. ALT62_BYTES = (string.DIGITS + string.ASCII_LOWERCASE + string.ASCII_UPPERCASE).encode("ascii") # Therefore, b'0' represents b'\0'. ALT62_ORDS = dict((x, i) for i, x in enumerate(ALT62_BYTES)) if HAVE_PYTHON3: ASCII62_BYTES = tuple(byte(x) for x in ASCII62_BYTES) ALT62_BYTES = tuple(byte(x) for x in ALT62_BYTES) # If you're going to make people type stuff longer than this length # I don't know what to tell you. Beyond this length powers # are computed, so be careful if you care about computation speed. # I think this is a VERY generous range. Decoding bytes fewer than 512 # will use this pre-computed lookup table, and hence, be faster. POW_62 = tuple(62 ** power for power in range(512)) def b62encode(raw_bytes, base_bytes=ASCII62_BYTES, _padding=True): """ Base62 encodes a sequence of raw bytes. Zero-byte sequences are
string.ASCII_LOWERCASE).encode("ascii") # Therefore, b"0" represents b"\0". ASCII62_ORDS = dict((x, i) for i, x in enumerate(ASCII62_BYTES)) # Really, I don't understand why people use the non-ASCII order, # but if you really like it that much, go ahead. Be my guest. Here # is what you will need: # # Does not follow ASCII order. ALT62_BYTES = (string.DIGITS + string.ASCII_LOWERCASE + string.ASCII_UPPERCASE).encode("ascii") # Therefore, b"0" represents b"\0". ALT62_ORDS = dict((x, i) for i, x in enumerate(ALT62_BYTES)) if _compat.HAVE_PYTHON3: ASCII62_BYTES = tuple(builtins.byte(x) for x in ASCII62_BYTES) ALT62_BYTES = tuple(builtins.byte(x) for x in ALT62_BYTES) # If you're going to make people type stuff longer than this length # I don't know what to tell you. Beyond this length powers # are computed, so be careful if you care about computation speed. # I think this is a VERY generous range. Decoding bytes fewer than 512 # will use this pre-computed lookup table, and hence, be faster. POW_62 = tuple(62**power for power in range(512)) def b62encode(raw_bytes, base_bytes=ASCII62_BYTES, _padding=True): """ Base62 encodes a sequence of raw bytes. Zero-byte sequences are preserved by default.
def _b85decode_chunks(encoded, base85_bytes, base85_ords): """Base-85 decodes. :param encoded: Encoded ASCII string. :param base85_bytes: Character set to use. :param base85_ords: A function to convert a base85 character to its ordinal value. You should not need to use this. :returns: Base-85-decoded raw bytes. """ # We want 5-tuple chunks, so pad with as many base85_ord == 84 characters # as required to satisfy the length. length = len(encoded) num_uint32s, remainder = divmod(length, 5) if remainder: padding_byte = builtins.byte(base85_bytes[84]) # "u"(ASCII85);"~"(RFC1924) padding_size = 5 - remainder encoded += padding_byte * padding_size num_uint32s += 1 length += padding_size else: padding_size = 0 #uint32s = [0] * num_uint32s uint32s = array.array("I", [0] * num_uint32s) j = 0 chunk = EMPTY_BYTE try: for i in builtins.range(0, length, 5): chunk = encoded[i:i + 5] # uint32_value = 0 # for char in chunk: # uint32_value = uint32_value * 85 + _base85_ords[char] # Above loop unrolled: uint32_value = ((((base85_ords[chunk[0]] * 85 + base85_ords[chunk[1]]) * 85 + base85_ords[chunk[2]]) * 85 + base85_ords[chunk[3]]) * 85 + base85_ords[chunk[4]]) # I've left this approach in here to warn you to NOT use it. # This results in a massive amount of calls to byte_ord inside # tight loops. # uint32_value = ((((base85_ords[byte_ord(chunk[0])] * # 85 + base85_ords[byte_ord(chunk[1])]) * # 85 + base85_ords[byte_ord(chunk[2])]) * # 85 + base85_ords[byte_ord(chunk[3])]) * # 85 + base85_ords[byte_ord(chunk[4])]) # Groups of characters that decode to a value greater than 2**32 − 1 # (encoded as "s8W-!") will cause a decoding error. Bad byte? if uint32_value > UINT32_MAX: # 2**32 - 1 raise OverflowError("Cannot decode chunk `%r`" % chunk) uint32s[j] = uint32_value j += 1 except KeyError: raise OverflowError("Cannot decode chunk `%r`" % chunk) raw_bytes = struct.pack(">" + "L" * num_uint32s, *uint32s) if padding_size: # Only as much padding added before decoding is removed after decoding. raw_bytes = raw_bytes[:-padding_size] return raw_bytes
ASCII62_ORDS = dict((x, i) for i, x in enumerate(ASCII62_BYTES)) # Really, I don't understand why people use the non-ASCII order, # but if you really like it that much, go ahead. Be my guest. Here # is what you will need: # # Does not follow ASCII order. ALT62_BYTES = (string.DIGITS + string.ASCII_LOWERCASE + string.ASCII_UPPERCASE).encode("ascii") # Therefore, b"0" represents b"\0". ALT62_ORDS = dict((x, i) for i, x in enumerate(ALT62_BYTES)) if _compat.HAVE_PYTHON3: ASCII62_BYTES = tuple(builtins.byte(x) for x in ASCII62_BYTES) ALT62_BYTES = tuple(builtins.byte(x) for x in ALT62_BYTES) # If you're going to make people type stuff longer than this length # I don't know what to tell you. Beyond this length powers # are computed, so be careful if you care about computation speed. # I think this is a VERY generous range. Decoding bytes fewer than 512 # will use this pre-computed lookup table, and hence, be faster. POW_62 = tuple(62 ** power for power in range(512)) def b62encode(raw_bytes, base_bytes=ASCII62_BYTES, _padding=True): """ Base62 encodes a sequence of raw bytes. Zero-byte sequences are
def _chr(c): return byte(c)