def b62encode_naive(raw_bytes, base_bytes=base62.ASCII62_BYTES, _padding=True, _zero_byte=ZERO_BYTE): """ Base62 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 ``ASCII62_CHARSET`` that uses natural ASCII order. :param _padding: (Internal) ``True`` (default) to include prefixed zero-byte sequence padding converted to appropriate representation. :returns: Base-62 encoded bytes. """ if not builtins.is_bytes(raw_bytes): raise TypeError("data must be raw bytes: got %r" % type(raw_bytes).__name__) number = integer.bytes_to_uint(raw_bytes) encoded = EMPTY_BYTE while number > 0: encoded = base_bytes[number % 62] + encoded number //= 62 # The following makes more divmod calls but is 2x faster. # number, remainder = divmod(number, 62) # encoded = _charset[remainder] + encoded if _padding: zero_leading = functional.leading(lambda w: w == _zero_byte[0], raw_bytes) encoded = (base_bytes[0] * zero_leading) + encoded return encoded
def b58decode_naive(encoded, _charset=base58.ASCII58_BYTES, _lookup=base58.ASCII58_ORDS): """ Simple implementation for benchmarking. Base-58 decodes a sequence of bytes into raw bytes. Whitespace is ignored. :param encoded: Base-58 encoded bytes. :param _charset: (Internal) The character set to use. Defaults to ``base58.ASCII58_BYTES`` that uses natural ASCII order. :param _lookup: (Internal) Ordinal-to-character lookup table for the specified character set. :returns: Raw bytes. """ if not builtins.is_bytes(encoded): raise TypeError("encoded data must be bytes: got %r" % type(encoded).__name__) # Ignore whitespace. encoded = re.sub(WHITESPACE_PATTERN, EMPTY_BYTE, encoded) # Convert to big integer. number = 0 for i, char in enumerate(reversed(encoded)): number += _lookup[char] * (58 ** i) # Obtain raw bytes. if number: raw_bytes = integer.uint_to_bytes(number) else: # We don't want to convert to b"\x00" when we get number == 0. # That would add an off-by-one extra zero byte in the result. raw_bytes = EMPTY_BYTE # Add prefixed padding if required. # 0 byte is represented using the first character in the character set. zero_char = _charset[0] # The extra [0] index in zero_byte_char[0] is for Python2.x-Python3.x # compatibility. Indexing into Python 3 bytes yields an integer, whereas # in Python 2.x it yields a single-byte string. zero_leading = functional.leading(lambda w: w == zero_char[0], encoded) if zero_leading: padding = ZERO_BYTE * zero_leading raw_bytes = padding + raw_bytes return raw_bytes
def b58decode_naive(encoded, _charset=base58.ASCII58_BYTES, _lookup=base58.ASCII58_ORDS): """ Simple implementation for benchmarking. Base-58 decodes a sequence of bytes into raw bytes. Whitespace is ignored. :param encoded: Base-58 encoded bytes. :param _charset: (Internal) The character set to use. Defaults to ``base58.ASCII58_BYTES`` that uses natural ASCII order. :param _lookup: (Internal) Ordinal-to-character lookup table for the specified character set. :returns: Raw bytes. """ if not builtins.is_bytes(encoded): raise TypeError("encoded data must be bytes: got %r" % type(encoded).__name__) # Ignore whitespace. encoded = re.sub(WHITESPACE_PATTERN, EMPTY_BYTE, encoded) # Convert to big integer. number = 0 for i, char in enumerate(reversed(encoded)): number += _lookup[char] * (58**i) # Obtain raw bytes. if number: raw_bytes = integer.uint_to_bytes(number) else: # We don't want to convert to b"\x00" when we get number == 0. # That would add an off-by-one extra zero byte in the result. raw_bytes = EMPTY_BYTE # Add prefixed padding if required. # 0 byte is represented using the first character in the character set. zero_char = _charset[0] # The extra [0] index in zero_byte_char[0] is for Python2.x-Python3.x # compatibility. Indexing into Python 3 bytes yields an integer, whereas # in Python 2.x it yields a single-byte string. zero_leading = functional.leading(lambda w: w == zero_char[0], encoded) if zero_leading: padding = ZERO_BYTE * zero_leading raw_bytes = padding + raw_bytes return raw_bytes
def test_full_count(self): self.assertEqual(leading(lambda w: w > 0, range(1, 10)), 9)
def test_start(self): self.assertEqual(leading(lambda w: w == "0", "0001"), 3) self.assertEqual(leading(lambda w: w == "0", "0001"), 3) self.assertEqual(leading(lambda w: w == "0", "0001", 1), 2)
def test_count(self): self.assertEqual(leading(lambda w: w > 0, [0, 0, 1]), 0) self.assertEqual(leading(lambda w: w > 1, [2, 2, 3, 0, 5]), 3) self.assertEqual(leading(lambda w: ord(w) >= ord('c'), "abalskjd"), 0) self.assertEqual(leading(lambda w: ord(w) >= ord('c'), "cuddleya"), 7)
def test_full_count(self): self.assertEqual(functional.leading(lambda w: w > 0, range(1, 10)), 9)
def test_start(self): self.assertEqual(functional.leading(lambda w: w == "0", "0001"), 3) self.assertEqual(functional.leading(lambda w: w == "0", "0001"), 3) self.assertEqual(functional.leading(lambda w: w == "0", "0001", 1), 2)
def test_count(self): self.assertEqual(functional.leading(lambda w: w > 0, [0, 0, 1]), 0) self.assertEqual(functional.leading(lambda w: w > 1, [2, 2, 3, 0, 5]), 3) self.assertEqual(functional.leading(lambda w: ord(w) >= ord("c"), "abalskjd"), 0) self.assertEqual(functional.leading(lambda w: ord(w) >= ord("c"), "cuddleya"), 7)