Skip to content

Instantly share code, notes, and snippets.

@antonyip
Created May 25, 2023 13:16
Show Gist options
  • Save antonyip/4051464832d61910670adeeba2d4b656 to your computer and use it in GitHub Desktop.
Save antonyip/4051464832d61910670adeeba2d4b656 to your computer and use it in GitHub Desktop.
from typing import Mapping, Union
# 58 character alphabet used
BITCOIN_ALPHABET = \
b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
RIPPLE_ALPHABET = b'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz'
XRP_ALPHABET = RIPPLE_ALPHABET
def scrub_input(v: Union[str, bytes]) -> bytes:
if isinstance(v, str):
v = v.encode('ascii')
return v
def _get_base58_decode_map(alphabet: bytes,
autofix: bool) -> Mapping[int, int]:
invmap = {char: index for index, char in enumerate(alphabet)}
if autofix:
groups = [b'0Oo', b'Il1']
for group in groups:
pivots = [c for c in group if c in invmap]
if len(pivots) == 1:
for alternative in group:
invmap[alternative] = invmap[pivots[0]]
return invmap
def b58decode_int(
v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET, *,
autofix: bool = False
) -> int:
"""
Decode a Base58 encoded string as an integer
"""
if b' ' not in alphabet:
v = v.rstrip()
v = scrub_input(v)
map = _get_base58_decode_map(alphabet, autofix=autofix)
decimal = 0
base = len(alphabet)
try:
for char in v:
decimal = decimal * base + map[char]
except KeyError as e:
raise ValueError(
"Invalid character {!r}".format(chr(e.args[0]))
) from None
return decimal
def b58decode(
v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET, *,
autofix: bool = False
) -> 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, autofix=autofix)
return acc.to_bytes(origlen - newlen + (acc.bit_length() + 7) // 8, 'big')
#hello
print(b58decode("Cn8eVZg"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment