TECHNICAL_DOC // KEYS / BASE58
BASE58
Base58 is a binary-to-text encoding using a 58-character alphabet designed
to be human-readable: it omits visually similar characters (0, O, I, l) and non-alphanumeric
symbols. Bitcoin uses Base58Check — Base58 with a 4-byte SHA256d checksum
appended — for legacy addresses (P2PKH, P2SH) and WIF private keys. SegWit addresses use
Bech32 instead.
BASE58_ALPHABET
THE 58 CHARACTERS
123456789 (9 digits, no 0)
ABCDEFGHJKLMNPQRSTUVWXYZ (24 uppercase, no I O)
abcdefghijkmnopqrstuvwxyz (25 lowercase, no l)
= 58 characters total
Excluded characters and why:
0 (zero) — confused with O
O (capital o) — confused with 0
I (capital i) — confused with l/1
l (lower L) — confused with I/1
+ / = — non-alphanumeric (URL/double-click hostile)
Result: any Base58 string can be:
- Read aloud unambiguously
- Selected by double-click
- Pasted into any URL field
BASE58CHECK_ENCODING
FULL ENCODING PROCEDURE
Input: payload bytes (e.g. version || hash160)
Step 1: Compute checksum
checksum = SHA256(SHA256(payload))[0:4] (4 bytes)
Step 2: Append checksum
data = payload || checksum
Step 3: Convert to big integer
n = bytes_to_int(data, big-endian)
Step 4: Repeated division by 58
while n > 0:
n, r = divmod(n, 58)
output = ALPHABET[r] + output
Step 5: Preserve leading zero bytes
for each leading 0x00 byte in data:
output = "1" + output
Result: Base58Check string
Decoding reverses the process and verifies checksum.
Mismatched checksum → invalid address (rejected).
Worked Example — P2PKH Address
EXAMPLE
Encoding the block/">genesis block coinbase pubkey hash into the famous "1A1zP1..." address.
Step 1: pubkey hash (20 bytes)
62E907B15CBF27D5425399EBF6F0FB50EBB88F18
Step 2: prepend version byte 0x00
00 62E907B15CBF27D5425399EBF6F0FB50EBB88F18
Step 3: SHA256d → take first 4 bytes
SHA256d(...) = C29B7D93...
checksum = C29B7D93
Step 4: append checksum
00 62E907B15CBF27D5425399EBF6F0FB50EBB88F18 C29B7D93
Step 5: Base58 encode (with leading 0x00 → "1")
→ 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
version-byte-base58check/">Version Byte → Address Prefix Mapping
REFERENCE
The first byte of the payload determines the visible address prefix. Different prefixes signal different network and address types.
Mainnet:
0x00 → "1..." P2PKH
0x05 → "3..." P2SH
0x80 → "5..." WIF uncompressed
0x80 → "K"/"L" WIF compressed (with 0x01 suffix)
0x0488B21E → "xpub..." extended public key
0x0488ADE4 → "xprv..." extended private key
Testnet:
0x6F → "m..." or "n..." P2PKH
0xC4 → "2..." P2SH
0xEF → "9..."/"c..." WIF
0x043587CF → "tpub..." extended pubkey
0x04358394 → "tprv..." extended privkey
TERMINOLOGY_INDEX
Base58
Encoding using 58 alphanumeric characters. Omits 0, O, I, l for readability.
Base58Check
Base58 with a 4-byte SHA256d checksum appended for error detection. Used by legacy addresses and WIF.
Checksum
First 4 bytes of SHA256(SHA256(payload)). Detects ~99.999998% of typos before broadcast.
Leading "1"
Encodes a leading 0x00 byte. Each "1" at the start of a P2PKH address represents a zero byte.
INTERACTIVE — TRY IT YOURSELF
ENCODING / KEYS
Base58Check
Bitcoin addresses aren't raw bytes — they're Base58Check-encoded strings. The format solves three problems at once: it eliminates visually confusing characters (
0 O l I), embeds a version byte that determines the address type, and appends a 4-byte checksum so any transcription error is detected with overwhelming probability.
THE ALPHABET PROBLEM
Base64 uses 64 printable characters. Bitcoin's Base58 removes 6 of them:
0 (zero), O (capital O), l (lowercase L), I (capital I), +, and /. The first four look too similar when handwritten or printed in small fonts. The last two cause problems in URLs and filenames.
BASE58 ALPHABET — HOVER TO SEE INDICES6 chars removed from base64
Removed characters shown in red. The resulting 58-character alphabet encodes more information per character than hexadecimal (58 vs 16) while staying human-readable and safe for voice dictation.
HOW BASE58CHECK WORKS
Base58Check takes a payload (like a 20-byte public key hash), prepends a version byte (1 byte that signals address type), and appends a 4-byte checksum computed as
SHA256(SHA256(version || payload))[0..3]. The whole thing is then Base58-encoded as one big number — leading zero-bytes become leading 1 characters.
LIVE BASE58CHECK ENCODERpaste hex payload below
ENCODE
DECODE
CHECKSUM PROTECTION — CLICK TO CORRUPT
The 4-byte checksum catches any single-character change with a 99.9999998% probability. It's not a security feature — it's an error-detection mechanism. The encoding guarantees that a mistyped character produces an invalid result, not a valid address belonging to someone else.
BIT-FLIP DEMO — CLICK ANY CHARACTER TO CORRUPT ITany change invalidates checksum
CHECKSUM VALID
VERSION BYTES — ADDRESS TYPE LOOKUP
The version byte is the secret behind why different address types start with different characters. A
0x00 version byte always produces an address starting with 1. A 0x05 version byte always starts with 3. This deterministic property means you can identify address type from the first character alone.
VERSION BYTE TABLE
| VERSION BYTE | B58 PREFIX | TYPE | PAYLOAD |
|---|
Why leading 1s? Leading zero-bytes in the payload produce leading
1 characters (index 0 in the alphabet). A P2PKH address has version byte 0x00 — one leading zero — so it always starts with exactly one 1. If the public key hash itself started with zero bytes, you'd see more 1s, but that's astronomically rare.