Пример #1
0
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)
Пример #2
0
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)
Пример #3
0
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)
Пример #4
0
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
Пример #5
0
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)
Пример #6
0
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
Пример #7
0
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]
Пример #8
0
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]
Пример #9
0
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
Пример #10
0
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
Пример #11
0
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)]
Пример #12
0
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
Пример #13
0
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
Пример #14
0
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)]
Пример #15
0
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)
Пример #16
0
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)
Пример #17
0
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
Пример #18
0
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
Пример #19
0
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
Пример #20
0
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
Пример #21
0
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
Пример #22
0
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
Пример #23
0
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
Пример #24
0
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
Пример #25
0
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
Пример #26
0
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.
Пример #27
0
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
Пример #28
0
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
Пример #29
0
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"))
Пример #30
0
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