Three base encoding schemes that look similar but solve different problems. Picking the wrong one can break URLs, confuse users, or add padding to JWTs.
Paste any 8 bytes into a Base64 encoder, a Base62 encoder, and a Base58 encoder, and you get three different strings. All three represent the same data. All three are reversible. None of them are encrypted. The outputs look like gibberish, but they are not: they are just different alphabets for writing binary data as printable text.
The choice between them is not arbitrary. Base64 is the right pick for email attachments, JWTs, and most web APIs. Base62 fits URL shortener IDs where you need no special characters. Base58 is designed for human-readable cryptocurrency addresses where visual ambiguity must be zero. Using the wrong one in the wrong context causes bugs that are subtle enough to reach production.
Binary data (bytes, files, keys, tokens) cannot always travel safely through systems that expect text. Email protocols, JSON fields, and URLs all have reserved characters or encoding assumptions. Base encoding solves this by representing arbitrary byte sequences using only characters from a predefined safe alphabet.
The "base" number is the alphabet size. Base64 uses 64 characters. Base62 uses 62. Base58 uses 58. Larger alphabets mean shorter output. Base64 represents 6 bits per character. Base62 represents slightly less, about 5.95 bits. Base58 represents slightly less still, about 5.86 bits. The efficiency differences are small in practice. The character set restrictions matter far more than the output length.
None of these are encryption. They are all publicly specified, fully reversible transformations that provide zero confidentiality. A Base64 string can be decoded in one second with a standard library function. This is worth stating explicitly because Base64 output looks like encrypted data and is routinely misused as if it were.
The alphabet
Base64 uses A to Z (26), a to z (26), 0 to 9 (10), + (1), / (1), for 64 characters total. Output is padded with = characters to make the length a multiple of 4.
``
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
``
The standard
RFC 4648 (published 2006, IETF) defines Base64 and several variants. The same RFC also defines Base32 and Base16. RFC 4648 superseded the earlier RFC 3548 and remains the current standard for Base64 in 2026.
The problem with URLs
RFC 3986 defines the characters permitted in a URL. The characters + and / are reserved. + means space in query strings (HTML form encoding), and / delimits URL path components. A Base64 string containing + or / will be misinterpreted or percent-encoded (%2B, %2F) by URL parsers.
The solution is Base64url, also defined in RFC 4648 Section 5: replace + with - and / with _. This produces URL-safe Base64. The = padding is often omitted in URL contexts. JWTs (JSON Web Tokens, RFC 7519) use Base64url with padding stripped, which is why JWT segments do not end in =. JWTs remain widely used in 2026 and continue to rely on Base64url without padding.
Where it belongs
Base64 is the right choice for email MIME attachments (defined in RFC 2045), JWT header/payload/signature encoding, encoding binary data in JSON or XML, and HTTP Basic authentication headers. The Base64 encoder/decoder handles both standard and URL-safe variants.
The alphabet
Base62 uses 0 to 9 (10), A to Z (26), a to z (26), for 62 characters total. No special characters at all.
``
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
``
The URL shortener use case
URL shorteners (bit.ly, t.co, tinyurl) need to encode a large integer, typically a row ID from a database, into a short string that can appear in a URL without any encoding. The integer 1,000,000 in Base62 is 4c92, four characters. In Base64, the same integer would produce output containing potential + or / characters requiring encoding.
Because Base62 uses only alphanumeric characters, the output is natively URL-safe without any character substitution. It also looks clean in a URL: https://short.example/4c92 is unambiguous in any browser or terminal.
JavaScript and BigInt limits
Base62 encoding of large integers (beyond Number.MAX_SAFE_INTEGER = 2^53 minus 1) requires BigInt in JavaScript. Standard Base62 libraries in Node.js handle this, but older code using parseInt() or float arithmetic will silently produce wrong results for IDs above about 9 quadrillion. This is a real production bug in URL shorteners that grow to scale. The Base62 encoder/decoder handles BigInt correctly.
The alphabet
Base58 uses 1 to 9 (9), A to H, J to N, P to Z (22), a to k, m to z (22), for 58 characters total. Specifically excluded are: 0 (zero), O (capital O), I (capital I), l (lowercase L).
``
123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
``
Satoshi Nakamoto's rationale
The Bitcoin source code comment in src/base58.h explains the exclusions directly: the alphabet is designed to avoid visually identical-looking characters, because 0/O and I/l look similar and can cause errors when copying. Bitcoin addresses are typically written on paper, typed manually, or printed on receipts, contexts where OCR or human transcription errors are possible.
Base58 also excludes + and / (as Base64 has them), avoiding URL encoding issues. The result is a character set designed for human handling: no character in Base58 can be confused with any other character, even in a low-quality font.
Base58Check
Bitcoin addresses and private keys use a variant called Base58Check, which appends a 4-byte checksum (the first 4 bytes of a double-SHA256 hash of the payload) before encoding. This means a mistyped character in a Bitcoin address will almost certainly produce an invalid checksum, preventing you from sending funds to a non-existent address. The checksum step is not part of basic Base58. It is a higher-level protocol. Other cryptocurrencies (Litecoin, Monero) use similar schemes. Use our Base58 encoder/decoder for the raw encoding.
Where Base58Check still stands in 2026
Bitcoin address encoding has evolved. SegWit (BIP 173, 2017) introduced Bech32 addresses starting with bc1q, and Taproot (BIP 350, 2021) uses Bech32m addresses starting with bc1p. These are replacing Base58Check for new address types. However, Base58Check is still used for legacy P2PKH addresses (starting with 1) and P2SH addresses (starting with 3), and for private keys in Wallet Import Format (WIF). If you are working with older Bitcoin wallets or importing private keys, Base58Check is still the encoding you will encounter.
| Property | Base64 | Base62 | Base58 |
|---|---|---|---|
| Alphabet size | 64 | 62 | 58 |
| Bits per character | 6 | ~5.95 | ~5.86 |
| Special characters | + / = | None | None |
| URL-safe (native) | No (use Base64url) | Yes | Yes |
| Human-copyable | No | Partially | Yes (designed for it) |
| Checksum variant | No | No | Base58Check |
| Standard document | RFC 4648 | None (de facto) | Bitcoin wiki / BIPs |
| Primary use | JWTs, email, APIs | URL shorteners, IDs | Cryptocurrency addresses |
Picking the right one
Use Base64 when you are following an existing standard (JWT, MIME, HTTP auth). Use Base62 when you need URL-safe short strings from integer IDs and you do not need a standard. Use Base58 when humans will read, copy, or type the output and correctness is critical.
For URL encoding of individual characters in a URL path or query string, which is a different operation from base encoding, use the URL encoder/decoder.
Building a URL shortener: Generate an auto-incrementing integer ID in your database. Encode it with Base62 to produce the short code. On redirect, decode the Base62 back to the integer and look up the original URL. The Base62 encoder/decoder shows the exact integer-to-string mapping.
Reading a JWT: A JWT has three parts separated by dots: header.payload.signature. Each part is Base64url-encoded without padding. Decoding the payload part reveals the JSON claims object: subject, expiration time, issued-at. No secret key is needed to decode the header and payload. They are not encrypted, only encoded. Our JWT decoder handles this.
Verifying a Bitcoin address: A legacy Bitcoin address (P2PKH format) starting with 1 is Base58Check encoded. If you remove the last 4 bytes (the checksum) and double-SHA256 the remainder, the first 4 bytes of that hash should match the bytes you removed. Any address that fails this check is invalid. The Base58 encoding ensures a transposition or typo in one character will produce a checksum failure. Newer Bech32 and Bech32m addresses (bc1q, bc1p) use a different checksum scheme, but the principle is the same: catch transcription errors before funds move.
All three are encodings, not encryption. Any Base64, Base62, or Base58 string can be decoded instantly by anyone without any key or secret. Do not store passwords as Base64. Do not transmit sensitive data over HTTP just because it "looks encoded." Encoding changes the representation of data. It does not protect it.
Base64 padding (= characters) causes issues in some URL contexts even when using the standard variant. Always use Base64url (with - and _ substitutions) in URLs, JWTs, and cookie values.
Base58 output is longer than Base62 output for the same input because the alphabet is smaller. For very large integers, this difference matters. Choose Base58 only when human readability and transcription safety are worth the extra characters.
Base62 has no formal RFC. Implementations disagree on alphabet ordering (whether digits come first or uppercase letters come first). If you exchange Base62 strings between systems, confirm both sides use the same alphabet order. The common convention, used by most URL shorteners, is digits first, then uppercase, then lowercase.
If you are working with JWTs, MIME attachments, or any binary data that needs to travel as text, start with the Base64 encoder/decoder. It supports both standard and URL-safe variants, handles padding correctly, and lets you paste raw bytes or text to see the encoded output instantly.
No. Base64 is a publicly documented encoding scheme defined in RFC 4648. Anyone can decode a Base64 string using a standard library in seconds, without any key or secret. It is used to represent binary data as text, not to hide data. Base64 provides zero confidentiality.
Base62 uses only alphanumeric characters (0 to 9, A to Z, a to z). None of these characters are reserved in URLs per RFC 3986, so a Base62 string can appear in a URL path or query string without any percent-encoding. This makes it a natural fit for URL shortener codes and short identifiers.
Base58Check is a variant of Base58 used in Bitcoin that appends a 4-byte checksum to the data before encoding. The checksum is the first 4 bytes of a double-SHA256 hash of the payload. This allows software and users to detect transcription errors in addresses. A single changed character will almost always produce a checksum mismatch. Base58Check is still used for legacy P2PKH addresses (starting with 1), P2SH addresses (starting with 3), and private keys in WIF format.
Base64 encodes 3 bytes at a time into 4 characters. If the input length is not a multiple of 3, padding = characters are added to make the output length a multiple of 4. One extra byte becomes two characters plus ==. Two extra bytes become three characters plus =. Base64url (used in JWTs) often strips this padding.
Base64 produces the shortest output because it has the largest alphabet (64 characters) and packs 6 bits per character. Base62 is slightly longer (~5.95 bits per character), and Base58 is slightly longer still (~5.86 bits per character). For most inputs the difference is a few percent, but at scale it adds up.
Base64 Encode / Decode
Encode text to Base64 or decode Base64 payloads with UTF-8-safe handling.
Base62 Encode/Decode
URL-safe encoding using alphanumeric characters for web applications and APIs.
Base58 Encode / Decode
Bitcoin and cryptocurrency encoding that avoids ambiguous characters for better readability.
URL Encoder/Decoder
Encode URLs for safe web use and decode URL-encoded strings back to original format.
JWT Decoder
Decode and view JSON Web Tokens to inspect headers, payload, and signature.
The Difference Between Encoding, Encryption, and Hashing
Base64 is not encryption. This guide defines encoding, encryption, and hashing precisely, runs the same input through each, and explains when to use which in production systems.
How SHA-256 Works: A Step-by-Step Walkthrough for Developers
SHA-256 is defined in NIST FIPS 180-4. This walkthrough explains padding, message schedule expansion, the 64-round compression function, and why you should never use SHA-256 for passwords.