aboutsummaryrefslogtreecommitdiff
path: root/frozen_deps/base58/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'frozen_deps/base58/__init__.py')
-rw-r--r--frozen_deps/base58/__init__.py130
1 files changed, 130 insertions, 0 deletions
diff --git a/frozen_deps/base58/__init__.py b/frozen_deps/base58/__init__.py
new file mode 100644
index 0000000..ff2fa18
--- /dev/null
+++ b/frozen_deps/base58/__init__.py
@@ -0,0 +1,130 @@
+'''Base58 encoding
+
+Implementations of Base58 and Base58Check encodings that are compatible
+with the bitcoin network.
+'''
+
+# This module is based upon base58 snippets found scattered over many bitcoin
+# tools written in python. From what I gather the original source is from a
+# forum post by Gavin Andresen, so direct your praise to him.
+# This module adds shiny packaging and support for python3.
+
+from hashlib import sha256
+from typing import Union
+
+__version__ = '2.0.1'
+
+# 58 character alphabet used
+BITCOIN_ALPHABET = \
+ b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
+RIPPLE_ALPHABET = b'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz'
+
+# Retro compatibility
+alphabet = BITCOIN_ALPHABET
+
+
+def scrub_input(v: Union[str, bytes]) -> bytes:
+ if isinstance(v, str):
+ v = v.encode('ascii')
+
+ return v
+
+
+def b58encode_int(
+ i: int, default_one: bool = True, alphabet: bytes = BITCOIN_ALPHABET
+) -> bytes:
+ """
+ Encode an integer using Base58
+ """
+ if not i and default_one:
+ return alphabet[0:1]
+ string = b""
+ while i:
+ i, idx = divmod(i, 58)
+ string = alphabet[idx:idx+1] + string
+ return string
+
+
+def b58encode(
+ v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET
+) -> bytes:
+ """
+ Encode a string using Base58
+ """
+ v = scrub_input(v)
+
+ nPad = len(v)
+ v = v.lstrip(b'\0')
+ nPad -= len(v)
+
+ p, acc = 1, 0
+ for c in reversed(v):
+ acc += p * c
+ p = p << 8
+ result = b58encode_int(acc, default_one=False, alphabet=alphabet)
+ return alphabet[0:1] * nPad + result
+
+
+def b58decode_int(
+ v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET
+) -> int:
+ """
+ Decode a Base58 encoded string as an integer
+ """
+ v = v.rstrip()
+ v = scrub_input(v)
+
+ decimal = 0
+ for char in v:
+ decimal = decimal * 58 + alphabet.index(char)
+ return decimal
+
+
+def b58decode(
+ v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET
+) -> bytes:
+ """
+ Decode a Base58 encoded string
+ """
+ v = v.rstrip()
+ v = scrub_input(v)
+
+ origlen = len(v)
+ v = v.lstrip(alphabet[0:1])
+ newlen = len(v)
+
+ acc = b58decode_int(v, alphabet=alphabet)
+
+ result = []
+ while acc > 0:
+ acc, mod = divmod(acc, 256)
+ result.append(mod)
+
+ return b'\0' * (origlen - newlen) + bytes(reversed(result))
+
+
+def b58encode_check(
+ v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET
+) -> bytes:
+ """
+ Encode a string using Base58 with a 4 character checksum
+ """
+ v = scrub_input(v)
+
+ digest = sha256(sha256(v).digest()).digest()
+ return b58encode(v + digest[:4], alphabet=alphabet)
+
+
+def b58decode_check(
+ v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET
+) -> bytes:
+ '''Decode and verify the checksum of a Base58 encoded string'''
+
+ result = b58decode(v, alphabet=alphabet)
+ result, check = result[:-4], result[-4:]
+ digest = sha256(sha256(result).digest()).digest()
+
+ if check != digest[:4]:
+ raise ValueError("Invalid checksum")
+
+ return result