How to encode and decode Base58Check
To encode:
- Paste the hex into Input · Hex: the version byte first, then the payload. Spaces, colons and
0xprefixes are accepted. - Read the result in Output · Base58Check. The tool computes the checksum and appends it before encoding.
- Keep Alphabet on Bitcoin for Bitcoin and most forks.
To decode, click Base58Check → Hex in the direction toggle and paste the address or key. The decoder converts it, recomputes the checksum, and returns the payload (still starting with the version byte) only if all 4 checksum bytes match. A single mistyped character gives “checksum mismatch: the string is mistyped or corrupted.”
What Base58Check adds to Base58
Plain Base58 has no error detection: a typo gives a different but equally valid string. Base58Check fixes that with two additions:
version (1 byte) | payload | first 4 bytes of SHA-256(SHA-256(version | payload))
The whole thing is then Base58 encoded, so leading zero bytes become 1s. The version byte picks the network and the type of data, and because it sits at the front of the number, it also fixes the first character of the result.
Version bytes and prefixes
The same 20-byte hash, 62e907b15cbf27d5425399ebf6f0fb50ebb88f18, with different version bytes:
| Version | Meaning | First character | Result |
|---|---|---|---|
00 | Bitcoin P2PKH address | 1 | 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa |
05 | Bitcoin P2SH address | 3 | 3Ai1JZ8pdJb2ksieUV8FsxSNVJCpoPi8W6 |
6f | Testnet P2PKH address | m or n | mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt |
c4 | Testnet P2SH address | 2 | 2N2GDNJ4rEm6NxfMC9ck8VuRdheQzXWaNZv |
The first row is the address that received the reward of the Bitcoin genesis block. The other rows only illustrate the version byte: wrapping a public key hash in a P2SH version byte does not give a usable P2SH address, since P2SH hashes a script.
WIF private keys
Wallet Import Format is Base58Check with version byte 80 and a 32-byte private key. A trailing 01 byte marks a key whose public key is used in compressed form. With the well-known example key from the Bitcoin wiki:
| Hex input | Base58Check |
|---|---|
80 + 0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D | 5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ |
the same + 01 | KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617 |
Uncompressed WIF keys start with 5, compressed ones with K or L. This example key is public; never use it for real funds.
Base58Check in Python
The checksum is two SHA-256 calls from the standard library. With a small Base58 encoder:
import hashlib
ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
def b58encode(data: bytes) -> str:
n = int.from_bytes(data, "big")
out = ""
while n:
n, r = divmod(n, 58)
out = ALPHABET[r] + out
zeros = len(data) - len(data.lstrip(b"\0"))
return "1" * zeros + out
def b58check(payload: bytes) -> str:
checksum = hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4]
return b58encode(payload + checksum)
b58check(bytes.fromhex("0062e907b15cbf27d5425399ebf6f0fb50ebb88f18"))
# '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa'
To verify a string in code, decode it with Base58, split off the last 4 bytes and compare them with the double hash of the rest. More Python byte handling is on the Python page.
Common problems
- Checksum mismatch. The string has a typo, was cut short, or is plain Base58 without a checksum (Solana addresses and IPFS hashes are plain Base58; use the Base58 decoder for them).
- “Too short to contain the 4-byte checksum”. The decoded value has fewer than 4 bytes, so it cannot be Base58Check.
- Unexpected character
"0","O","I"or"l". Not in the Base58 alphabet; check the transcription. - Wrong first character after encoding. Check the version byte. Without it, a 20-byte hash usually encodes to a string that does not start with
1.
FAQ
How is the Base58Check checksum calculated?
Hash the payload (version byte included) with SHA-256, hash the result with SHA-256 again, and take the first 4 bytes. Those 4 bytes are appended before the Base58 encoding.
Does a valid checksum mean the address is safe to send to?
It means the string was not mistyped: a random typo passes with a chance of about 1 in 4.3 billion. It says nothing about who controls the address or whether it belongs to the network you think it does.
Can Base58Check decode bc1 addresses?
No. Addresses starting with bc1 are Bech32 or Bech32m (SegWit and Taproot), which use a different alphabet and a different checksum.
Should I paste a real private key here?
The conversion runs in your browser and the page blocks all network requests except Cloudflare’s page-view count, but a WIF key controls funds. Use a test key, or an offline machine, for anything that holds value.