Base58Check Encode and Verify
Encode payloads as Base58 with a double SHA-256 checksum, preserve leading zero bytes, and reject corrupted input on decode.
Code
import hashlib
ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
def b58encode(raw: bytes) -> str:
number = int.from_bytes(raw, "big")
digits: list[str] = []
while number:
number, remainder = divmod(number, 58)
digits.append(ALPHABET[remainder])
leading_zeros = len(raw) - len(raw.lstrip(b"\0"))
return ALPHABET[0] * leading_zeros + "".join(reversed(digits))
def b58decode(text: str) -> bytes:
number = 0
for char in text:
index = ALPHABET.find(char)
if index < 0:
raise ValueError(f"invalid base58 character: {char!r}")
number = number * 58 + index
body = number.to_bytes((number.bit_length() + 7) // 8, "big") if number else b""
leading_ones = len(text) - len(text.lstrip(ALPHABET[0]))
return b"\0" * leading_ones + body
def checksum(payload: bytes) -> bytes:
first = hashlib.sha256(payload).digest()
return hashlib.sha256(first).digest()[:4]
def encode_check(payload: bytes) -> str:
return b58encode(payload + checksum(payload))
def decode_check(text: str) -> bytes:
raw = b58decode(text)
if len(raw) < 5:
raise ValueError("input too short to contain a checksum")
payload, supplied = raw[:-4], raw[-4:]
if checksum(payload) != supplied:
raise ValueError("checksum mismatch")
return payload
if __name__ == "__main__":
token = encode_check(b"\x00hello")
print(token, decode_check(token))
corrupted = token[:-1] + ("1" if token[-1] != "1" else "2")
try:
decode_check(corrupted)
except ValueError as error:
print("rejected:", error)
Report a problem with this exampleOpens a pre-filled issue on GitHub.