Skip to main content
{/}codefunc
Web & APIAugust 2, 2026 · 6 min read

Base58 Encoding Explained: Bitcoin Addresses, IPFS CIDs, and Compact IDs

Learn when Base58 beats Base64 — alphabet rules, leading-zero handling, checksum variants, and how to encode or decode safely in the browser.

By codefunc

base58encodingbitcoinipfsbase64base32

Base58 shows up whenever a system needs a short, human-friendly encoding of binary data: Bitcoin and many cryptocurrency addresses, IPFS content identifiers (CIDs), and some compact ID schemes. It looks like Base64 at a glance, but the alphabet, padding rules, and leading-zero behavior are different enough that a wrong decoder silently produces garbage — or worse, an address that looks valid and is not.

Bottom line: Use Base58 when you need a URL-safe, copy-paste-friendly encoding without ambiguous characters (0/O/I/l). Use Base64 for MIME and HTTP; use Base32 when case-insensitivity matters. Encode and decode with a client-side Base58 tool when the payload is sensitive — no data needs to leave your browser.

Who this guide is for

Frontend and backend developers who paste wallet addresses, debug IPFS hashes, or build systems that emit short public IDs. If you have ever wondered why Bitcoin addresses refuse 0, O, I, and l, this guide covers the encoding rules and the practical failure modes.

What Base58 actually is

Base58 maps binary data to a 58-character alphabet. The common Bitcoin/IPFS alphabet is:

123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz

Compared with Base64, Base58 drops six characters that cause transcription errors:

Dropped Why
0 (zero) Confused with O
O (capital o) Confused with 0
I (capital i) Confused with l / 1
l (lowercase L) Confused with I / 1
+ and / Unsafe or awkward in URLs and filenames

There is no padding. Output length grows with input size, but you never see trailing = the way you do with Base64.

Base58 vs Base64 vs Base32

Property Base58 Base64 Base32
Alphabet size 58 64 32
Case sensitive Yes Yes Usually no (Crockford / RFC)
Padding None = common = common (RFC)
Ambiguous chars Avoided by design Includes + / Alphabet varies
Typical use Addresses, CIDs, short IDs MIME, data URLs, tokens ULIDs, TOTP secrets
Expansion ~1.37× binary ~1.33× binary ~1.6× binary

Reach for Base64 when interoperability with HTTP, PEM, or JWT tooling matters. Reach for Base32 when humans will type the string and case should not matter. Reach for Base58 when the string will be spoken, printed, or pasted into wallets and content-addressed systems.

How encoding works (conceptually)

Treat the input bytes as a big-endian integer. Convert that integer to base 58 using the alphabet above. Leading zero bytes in the input become leading 1 characters in the output — not a quirk, a deliberate rule so leading zeros are not lost when the integer value would otherwise drop them.

Example intuition (not a full wallet address):

Input bytes with leading 0x00 → output starts with "1"

If your decoder ignores leading 1s, checksums and address validation will fail in ways that are hard to debug. Always use a Base58 implementation that documents leading-zero handling.

Base58Check and checksums

Plain Base58 is just an alphabet. Many crypto systems use Base58Check:

  1. Payload bytes (version byte + data)
  2. Double SHA-256 of the payload; take the first 4 bytes as checksum
  3. Append checksum to payload
  4. Encode the whole thing with Base58

That checksum catches typos before funds move. A single wrong character usually fails the checksum rather than resolving to a different valid address. When you decode an address for debugging, distinguish:

  • Base58 decode — alphabet → bytes
  • Base58Check decode — alphabet → bytes, then verify checksum

Paste workflows on codefunc stay in the browser; confirm whether your tool or library expects the checksummed variant before you trust a round-trip.

Where you will see Base58

Cryptocurrency addresses

Classic Bitcoin P2PKH addresses start with 1, P2SH with 3, and many bech32 addresses use a different encoding entirely (bc1…). Not every "crypto string" is Base58 — Solana public keys often use Base58, while Ethereum addresses are hex with a 0x prefix. Always check the chain's encoding docs before writing a validator.

IPFS and content addressing

IPFS CIDv0 looks like a multihash encoded in Base58btc (often starting with Qm…). CIDv1 can use multiple bases (bafy… is Base32 for the multibase prefix). If a CID fails to parse, the first question is which multibase prefix and CID version you have — not whether Base58 is "broken."

Application IDs

Some products use Base58 for invite codes or resource IDs because the alphabet is dense and URL-safe without percent-encoding. That is fine for public IDs. Do not treat Base58 as encryption or as a substitute for access control.

Encoding and decoding in practice

In application code, prefer a well-tested library that matches the alphabet you need (Bitcoin vs Flickr Base58 differ slightly). For ad-hoc debugging:

  1. Confirm alphabet (Bitcoin/IPFS is the usual default).
  2. Confirm whether checksum verification applies.
  3. Round-trip a known vector before trusting production data.
  4. Use a client-side Base58 encoder/decoder so wallet keys and CIDs never hit an upload API.

When you only need generic binary-safe text for HTTP or email, skip Base58 and use Base64. When you need case-insensitive secrets (for example TOTP), prefer Base32.

Common failure modes

Symptom Likely cause Fix
Decode throws / invalid character Wrong alphabet or Base64 pasted by mistake Check for +, /, =, or dropped chars
Round-trip loses leading zeros Decoder drops leading 1s Use a Base58-aware library
Address checksum fails Typo or wrong version byte Re-copy; verify Base58Check
CID will not resolve CIDv1/multibase, not Base58btc Inspect prefix (Qm vs bafy)
"Looks like Base58" but fails Bech32 / hex / Base64url Identify format before decoding

Privacy and operational hygiene

Wallet seeds, private keys, and unsigned transaction blobs should never go to a random online converter. Prefer tools that run entirely in your browser: paste, transform, copy — with no upload of the payload. After first load, you can work offline. On a shared machine, clear the tab when finished.

Rule of thumb: If the string can move money or unlock a keystore, treat it like a password — local tooling only.

Choosing an encoding for new systems

Ask three questions:

  1. Will humans type this? Prefer Base32 or Base58 over Base64.
  2. Must it be case-insensitive? Prefer Base32.
  3. Must it interoperate with MIME, PEM, or JWTs? Prefer Base64 / Base64url.

For new public IDs in a typical web app, Nano ID or ULID often beat inventing a custom Base58 scheme — unless you are integrating with Bitcoin, IPFS, or an existing Base58 ecosystem.

Use these codefunc tools alongside this guide:

Practical takeaway

Base58 is a human-friendly binary encoding optimized for copy-paste and OCR, not for HTTP transport. Remember the alphabet exclusions, leading-1 zero handling, and the Base58Check checksum used by many crypto addresses. Pick Base64 for web transport, Base32 for case-insensitive secrets, and Base58 when you speak the language of wallets and CIDs. Decode locally with Base58 when the string is sensitive — no data needs to leave your machine.

Sources

Try it on codefunc

Related articles

3

Search tools

Find a developer tool