def ichunks(iterable, size, *args, **kwargs): """Splits an iterable into iterators for chunks each of specified size. :param iterable: The iterable to split. Must be an ordered sequence to guarantee order. :param size: Chunk size. :param padding: If a pad value is specified appropriate multiples of it will be appended to the end of the iterator if the size is not an integral multiple of the length of the iterable: map(tuple, ichunks("aaabccd", 3, "-")) -> [("a", "a", "a"), ("b", "c", "c"), ("d", "-", "-")] map(tuple, ichunks("aaabccd", 3, None)) -> [("a", "a", "a"), ("b", "c", "c"), ("d", None, None)] If no padding is specified, nothing will be appended if the chunk size is not an integral multiple of the length of the iterable. That is, the last chunk will have chunk size less than the specified chunk size. :yields: Generator of chunk iterators. """ length = len(iterable) if args or kwargs: padding = kwargs["padding"] if kwargs else args[0] for i in builtins.range(0, length, size): yield itertools.islice( chain(iterable, itertools.repeat(padding, (size - (length % size)))), i, i + size) else: for i in builtins.range(0, length, size): yield itertools.islice(iterable, i, i + size)
def permutations(iterable, r=None): """Return successive `r` length permutations of elements in the `iterable`. If `r` is not specified or is ``None``, then `r` defaults to the length of the `iterable` and all possible full-length permutations are generated. Permutations are emitted in lexicographic sort order. So, if the input `iterable` is sorted, the permutation tuples will be produced in sorted order. Elements are treated as unique based on their position, not on their value. So if the input elements are unique, there will be no repeating value in each permutation. The number of items returned is ``n! / (n - r)!`` when ``0 <= r <= n`` or zero when `r > n`. .. note:: Software and documentation for this function are taken from CPython, :ref:`license details <psf-license>`. """ pool = tuple(iterable) pool_length = len(pool) r = pool_length if r is None else r for indices in product(builtins.range(pool_length), repeat=r): if len(set(indices)) == r: yield tuple(pool[i] for i in indices)
def uint_to_bytes_pycrypto(uint, blocksize=0): """long_to_bytes(n:long, blocksize:int) : string Convert a long integer to a byte string. If optional blocksize is given and greater than zero, pad the front of the byte string with binary zeros so that the length is a multiple of blocksize. """ # after much testing, this algorithm was deemed to be the fastest raw_bytes = EMPTY_BYTE uint = int(uint) while uint > 0: raw_bytes = struct.pack(">I", uint & 0xffffffff) + raw_bytes uint >>= 32 # strip off leading zeros i = 0 for i in builtins.range(len(raw_bytes)): if raw_bytes[i] != ZERO_BYTE[0]: break else: # only happens when n == 0 raw_bytes = ZERO_BYTE i = 0 raw_bytes = raw_bytes[i:] # add back some pad bytes. this could be done more efficiently w.r.t. the # de-padding being done above, but sigh... if blocksize > 0 and len(raw_bytes) % blocksize: raw_bytes = (blocksize - len(raw_bytes) % blocksize) * ZERO_BYTE + raw_bytes return raw_bytes
def chunks(iterable, size, *args, **kwargs): """Splits an iterable into materialized chunks each of specified size. :param iterable: The iterable to split. Must be an ordered sequence to guarantee order. :param size: Chunk size. :param padding: This must be an iterable or None. So if you want a ``True`` filler, use [True] or (True, ) depending on whether the iterable is a list or a tuple. Essentially, it must be the same type as the iterable. If a pad value is specified appropriate multiples of it will be concatenated at the end of the iterable if the size is not an integral multiple of the length of the iterable: tuple(chunks("aaabccd", 3, "-")) -> ("aaa", "bcc", "d--") tuple(chunks((1, 1, 1, 2, 2), 3, (None,))) -> ((1, 1, 1, ), (2, 2, None)) If no padding is specified, nothing will be appended if the chunk size is not an integral multiple of the length of the iterable. That is, the last chunk will have chunk size less than the specified chunk size. :yields: Generator of materialized chunks. """ length = len(iterable) if args or kwargs: padding = kwargs["padding"] if kwargs else args[0] if padding is None: if builtins.is_bytes_or_unicode(iterable): padding = "" elif isinstance(iterable, tuple): padding = (padding,) else: iterable = list(iterable) padding = [padding] sequence = iterable + (padding * (size - (length % size))) for i in builtins.range(0, length, size): yield sequence[i:i + size] else: for i in builtins.range(0, length, size): yield iterable[i:i + size]
def chunks(iterable, size, *args, **kwargs): """Splits an iterable into materialized chunks each of specified size. :param iterable: The iterable to split. Must be an ordered sequence to guarantee order. :param size: Chunk size. :param padding: This must be an iterable or None. So if you want a ``True`` filler, use [True] or (True, ) depending on whether the iterable is a list or a tuple. Essentially, it must be the same type as the iterable. If a pad value is specified appropriate multiples of it will be concatenated at the end of the iterable if the size is not an integral multiple of the length of the iterable: tuple(chunks("aaabccd", 3, "-")) -> ("aaa", "bcc", "d--") tuple(chunks((1, 1, 1, 2, 2), 3, (None,))) -> ((1, 1, 1, ), (2, 2, None)) If no padding is specified, nothing will be appended if the chunk size is not an integral multiple of the length of the iterable. That is, the last chunk will have chunk size less than the specified chunk size. :yields: Generator of materialized chunks. """ length = len(iterable) if args or kwargs: padding = kwargs["padding"] if kwargs else args[0] if padding is None: if builtins.is_bytes_or_unicode(iterable): padding = "" elif isinstance(iterable, tuple): padding = (padding, ) else: iterable = list(iterable) padding = [padding] sequence = iterable + (padding * (size - (length % size))) for i in builtins.range(0, length, size): yield sequence[i:i + size] else: for i in builtins.range(0, length, size): yield iterable[i:i + size]
def random_shuffle(sequence, rand_func=generate_random_bytes): """ Randomly shuffles the sequence in-place. :param sequence: Sequence to shuffle in-place. :returns: The shuffled sequence itself (for convenience). """ copy = list(sequence) # Choose a random item (without replacement) until all the items have been # chosen. for i in builtins.range(len(sequence)): random_uint = generate_random_uint_between(0, len(copy), rand_func) sequence[i] = copy[random_uint] del copy[random_uint] return sequence
def generate_random_sequence(length, pool, rand_func=generate_random_bytes): """ Generates a random sequence of given length using the sequence pool specified. :param length: The length of the random sequence. :param pool: A sequence of elements to be used as the pool from which random elements will be chosen. :returns: A list of elements randomly chosen from the pool. """ if not builtins.is_integer(length): raise TypeError("Length must be a positive integer: got `%r`" % type(length).__name__) if length <= 0: raise ValueError("length must be a positive integer: got %d" % length) return [random_choice(pool, rand_func) for _ in builtins.range(length)]
def find(predicate, iterable, start=0): """Determines the first index where the predicate is true for an element in the iterable. :param predicate: Predicate function of the form:: f(x) -> bool :param iterable: Iterable sequence. :param start: Start index. :returns: -1 if not found; index (>= start) if found. """ for i in builtins.range(start, len(iterable)): if predicate(iterable[i]): return i return -1
def combinations_with_replacement(iterable, r): """Return `r` length sub-sequences of elements from the `iterable` allowing individual elements to be replaced more than once. Combinations are emitted in lexicographic sort order. So, if the input `iterable` is sorted, the combinations tuples will be produced in sorted order. Elements are treated as unique based on their position, not on their value. So if the input elements are unique, the generated combinations will also be unique. The number of items returned is ``(n + r - 1)! / r! / (n - 1)!`` when ``n > 0``. .. note:: Software and documentation for this function are taken from CPython, :ref:`license details <psf-license>`. """ pool = tuple(iterable) n = len(pool) for indices in product(builtins.range(n), repeat=r): if sorted(indices) == list(indices): yield tuple(pool[i] for i in indices)
def uint_to_bytes_naive_array_based(uint, chunk_size=0): """ Converts an integer into bytes. :param uint: Unsigned integer value. :param chunk_size: Chunk size. :returns: Bytes. """ if uint < 0: raise ValueError("Negative numbers cannot be used: %i" % uint) if uint == 0: bytes_count = 1 else: bytes_count = builtins.integer_byte_length(uint) byte_array = array.array("B", [0] * bytes_count) for count in builtins.range(bytes_count - 1, -1, -1): byte_array[count] = uint & 0xff uint >>= 8 raw_bytes = byte_array.tostring() if chunk_size > 0: # Bounds checking. We're not doing this up-front because the # most common use case is not specifying a chunk size. In the worst # case, the number will already have been converted to bytes above. length = len(raw_bytes) bytes_needed = bytes_count if bytes_needed > chunk_size: raise OverflowError( "Need %d bytes for number, but chunk size is %d" % (bytes_needed, chunk_size)) remainder = length % chunk_size if remainder: raw_bytes = (chunk_size - remainder) * ZERO_BYTE + raw_bytes return raw_bytes
def _pure_is_prime(num, iterations=5, _sieve=prime_sieve.SIEVE): """Determines whether a number is prime. :param num: Number :param iterations: Number of iterations. :returns: ``True`` if prime; ``False`` otherwise. """ # Trial division with sieve for prime_number in _sieve: if prime_number >= num: return True if not num % prime_number: return False # Passed trial division, proceed to Rabin-Miller # Rabin-Miller implemented per Ferguson & Schneier # Compute s, t for Rabin-Miller num_s, num_t = num - 1, 0 while not num_s % 2: num_s, num_t = num_s // 2, num_t + 1 # Repeat Rabin-Miller x times base = 2 # Use 2 as a base for first iteration speedup, per HAC for _ in builtins.range(iterations): num_v = _pure_pow_mod(base, num_s, num) if num_v == 1: continue i = 0 while num_v != num - 1: if i == num_t - 1: return False else: num_v, i = _pure_pow_mod(num_v, 2, num), i + 1 base = random.generate_random_uint_between(2, num) return True
def bytes_to_uint_naive(raw_bytes, _zero_byte=ZERO_BYTE): """ Converts bytes (base-256 representation) to integer:: bytes_to_integer(bytes) : integer This is (essentially) the inverse of integer_to_bytes(). Encode your Unicode strings to a byte encoding before converting them. .. WARNING: Does not preserve leading zero bytes. :param raw_bytes: Raw bytes (base-256 representation). :returns: Integer. """ if not builtins.is_bytes(raw_bytes): raise TypeError("argument must be raw bytes: got %r" % type(raw_bytes).__name__) length = len(raw_bytes) remainder = length % 4 if remainder: # Ensure we have a length that is a multiple of 4 by prefixing # sufficient zero padding. padding_size = 4 - remainder length += padding_size raw_bytes = _zero_byte * padding_size + raw_bytes # Now unpack integers and accumulate. int_value = 0 for i in builtins.range(0, length, 4): chunk = raw_bytes[i:i + 4] int_value = (int_value << 32) + struct.unpack(">I", chunk)[0] return int_value
def uint_to_bytes_naive_array_based(uint, chunk_size=0): """ Converts an integer into bytes. :param uint: Unsigned integer value. :param chunk_size: Chunk size. :returns: Bytes. """ if uint < 0: raise ValueError("Negative numbers cannot be used: %i" % uint) if uint == 0: bytes_count = 1 else: bytes_count = builtins.integer_byte_length(uint) byte_array = array.array("B", [0] * bytes_count) for count in builtins.range(bytes_count - 1, -1, -1): byte_array[count] = uint & 0xff uint >>= 8 raw_bytes = byte_array.tostring() if chunk_size > 0: # Bounds checking. We're not doing this up-front because the # most common use case is not specifying a chunk size. In the worst # case, the number will already have been converted to bytes above. length = len(raw_bytes) bytes_needed = bytes_count if bytes_needed > chunk_size: raise OverflowError("Need %d bytes for number, but chunk size is %d" % (bytes_needed, chunk_size)) remainder = length % chunk_size if remainder: raw_bytes = (chunk_size - remainder) * ZERO_BYTE + raw_bytes return raw_bytes
def uint_to_bytes_array_based(number, chunk_size=0): """ Convert a integer to bytes (base-256 representation):: integer_to_bytes(n:int, chunk_size:int) : string .. WARNING: Does not preserve leading zeros if you don't specify a chunk size. :param number: Integer value :param chunk_size: If optional chunk size is given and greater than zero, pad the front of the byte string with binary zeros so that the length is a multiple of ``chunk_size``. Raises an OverflowError if the chunk_size is not sufficient to represent the integer. :returns: Raw bytes (base-256 representation). :raises: ``OverflowError`` when block_size is given and the number takes up more bytes than fit into the block. """ # Machine word aligned byte array based implementation. if number < 0: raise ValueError("Number must be unsigned integer: %d" % number) raw_bytes = EMPTY_BYTE if not number: raw_bytes = ZERO_BYTE # Align packing to machine word size. num = number word_bits, word_bytes, max_uint, pack_type = _compat.get_word_alignment( num) pack_format = ">" + pack_type temp_buffer = array.array("B", [0] * word_bytes) byte_array = array.array("B", raw_bytes) while num > 0: struct.pack_into(pack_format, temp_buffer, 0, num & max_uint) byte_array = temp_buffer + byte_array num >>= word_bits # Count the number of zero prefix bytes. zero_leading = 0 length = len(byte_array) for zero_leading in builtins.range(length): if byte_array[zero_leading]: break raw_bytes = byte_array[zero_leading:].tostring() if chunk_size > 0: # Bounds checking. We're not doing this up-front because the # most common use case is not specifying a chunk size. In the worst # case, the number will already have been converted to bytes above. length = len(raw_bytes) if length > chunk_size: raise OverflowError( "Need %d bytes for number, but chunk size is %d" % (length, chunk_size)) remainder = length % chunk_size if remainder: raw_bytes = (chunk_size - remainder) * ZERO_BYTE + raw_bytes return raw_bytes
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. :param raw_bytes: Raw bytes to encode. :param base_bytes: The character set to use. Defaults to ``ASCII58_BYTES`` that uses natural ASCII order. :param _padding: (Internal) ``True`` (default) to include prefixed zero-byte sequence
def _pure_pow_mod(base, power, modulus): """Calculates: base**pow mod modulus Uses multi bit scanning with nBitScan bits at a time. From Bryan G. Olson's post to comp.lang.python Does left-to-right instead of pow()'s right-to-left, thus about 30% faster than the python built-in with small bases :param base: Base :param power: Power :param modulus: Modulus :returns: base**pow mod modulus """ n_bit_scan = 5 # NOTE(TREV): Added support for negative exponents negative_result = False if power < 0: power *= -1 negative_result = True #exp2 = 2**n_bit_scan exp2 = 1 << n_bit_scan mask = exp2 - 1 # Break power into a list of digits of nBitScan bits. # The list is recursive so easy to read in reverse direction. nibbles = None while power: nibbles = int(power & mask), nibbles power >>= n_bit_scan # Make a table of powers of base up to 2**nBitScan - 1 low_powers = [1] for i in builtins.range(1, exp2): low_powers.append((low_powers[i - 1] * base) % modulus) # To exponentiate by the first nibble, look it up in the table nib, nibbles = nibbles prod = low_powers[nib] # For the rest, square nBitScan times, then multiply by # base^nibble while nibbles: nib, nibbles = nibbles for i in builtins.range(n_bit_scan): prod = (prod * prod) % modulus if nib: prod = (prod * low_powers[nib]) % modulus # NOTE(TREV): Added support for negative exponents if negative_result: prod_inv = inverse_mod(prod, modulus) # Check to make sure the inverse is correct assert (prod * prod_inv) % modulus == 1 return prod_inv return prod
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. :param raw_bytes: Raw bytes to encode. :param base_bytes: The character set to use. Defaults to ``ASCII58_BYTES`` that uses natural ASCII order. :param _padding: (Internal) ``True`` (default) to include prefixed zero-byte sequence padding converted to appropriate representation.
def uint_to_bytes_array_based(number, chunk_size=0): """ Convert a integer to bytes (base-256 representation):: integer_to_bytes(n:int, chunk_size:int) : string .. WARNING: Does not preserve leading zeros if you don't specify a chunk size. :param number: Integer value :param chunk_size: If optional chunk size is given and greater than zero, pad the front of the byte string with binary zeros so that the length is a multiple of ``chunk_size``. Raises an OverflowError if the chunk_size is not sufficient to represent the integer. :returns: Raw bytes (base-256 representation). :raises: ``OverflowError`` when block_size is given and the number takes up more bytes than fit into the block. """ # Machine word aligned byte array based implementation. if number < 0: raise ValueError("Number must be unsigned integer: %d" % number) raw_bytes = EMPTY_BYTE if not number: raw_bytes = ZERO_BYTE # Align packing to machine word size. num = number word_bits, word_bytes, max_uint, pack_type = _compat.get_word_alignment(num) pack_format = ">" + pack_type temp_buffer = array.array("B", [0] * word_bytes) byte_array = array.array("B", raw_bytes) while num > 0: struct.pack_into(pack_format, temp_buffer, 0, num & max_uint) byte_array = temp_buffer + byte_array num >>= word_bits # Count the number of zero prefix bytes. zero_leading = 0 length = len(byte_array) for zero_leading in builtins.range(length): if byte_array[zero_leading]: break raw_bytes = byte_array[zero_leading:].tostring() if chunk_size > 0: # Bounds checking. We're not doing this up-front because the # most common use case is not specifying a chunk size. In the worst # case, the number will already have been converted to bytes above. length = len(raw_bytes) if length > chunk_size: raise OverflowError("Need %d bytes for number, but chunk size is %d" % (length, chunk_size)) remainder = length % chunk_size if remainder: raw_bytes = (chunk_size - remainder) * ZERO_BYTE + raw_bytes return raw_bytes
b = builtins.b ZERO_BYTE = _compat.ZERO_BYTE UINT128_MAX = _compat.UINT128_MAX UINT32_MAX = _compat.UINT32_MAX EMPTY_BYTE = _compat.EMPTY_BYTE EXCLAMATION_CHUNK = b("!!!!!") ZERO_GROUP_CHAR = b("z") # Use this if you want the base85 codec to encode/decode including # ASCII85 prefixes/suffixes. ASCII85_PREFIX = b("<~") ASCII85_SUFFIX = b("~>") # ASCII85 characters. ASCII85_BYTES = array.array("B", [(num + 33) for num in builtins.range(85)]) # 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. # ASCII85_ORDS = array.array("B", [255] * 128) # for ordinal, _byte in enumerate(ASCII85_BYTES): # ASCII85_ORDS[_byte] = ordinal # http://tools.ietf.org/html/rfc1924 RFC1924_BYTES = array.array("B", (string.DIGITS + string.ASCII_UPPERCASE + string.ASCII_LOWERCASE + "!#$%&()*+-;<=>?@^_`{|}~").encode("ascii"))
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