DevToys Web Pro iconDevToys Web ProBlogg
Vurder oss:
Prøv nettleserutvidelsen:
← Back to Blog

Base62 Encoding Guide: URL-Safe Short IDs Without Padding or Special Characters

7 min read

Base62 is a radix-62 number system that uses exactly 62 alphanumeric characters — 09, AZ, and az — to represent integers as compact, URL-safe strings. You have seen it every time you clicked a bit.ly link or used a YouTube video ID. Try it yourself with the Base62 encoder/decoder while following along with this guide.

The Base62 Alphabet

The full 62-character alphabet, with each character representing its positional value from 0 to 61, is:

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

Every character is alphanumeric. There are no +, /, or = characters that would need percent-encoding in a URL. There are no ambiguous pairs like 0/O or l/I that Base58 removes — Base62 keeps the full alphanumeric set and relies on context (monospaced fonts, copy-paste) rather than character removal for readability.

How Base62 Differs from Base64

Base64 and Base62 look similar but solve fundamentally different problems and operate on different inputs.

Base64 is a byte codec. It takes arbitrary binary data, groups bytes into 3-byte (24-bit) blocks, and maps each block to four 6-bit characters from a 64-character alphabet. When the input is not a multiple of 3 bytes, it appends = or == padding. Base64 is ideal for encoding binary blobs — images, certificates, encrypted payloads — because it handles any byte sequence uniformly.

Base62 is typically an integer-to-string radix conversion. You treat the input as a large integer and repeatedly divide by 62, collecting remainders to build the output string. Because there is no fixed block size there is no need for padding. The tradeoff is that Base62 is not a general byte codec: it works naturally on non-negative integers, and encoding arbitrary byte strings requires treating the bytes as a big-endian integer, which adds complexity and may not preserve leading zero bytes faithfully without special handling.

The practical consequence: use Base64 to encode binary data for transport; use Base62 to convert an auto-increment database ID into a short, URL-safe slug.

Base62 vs Base64 vs Base58 vs Hex

EncodingAlphabet sizePaddingURL-safeAmbiguous charsTypical use
Hex (Base16)16NoYesNoHash digests, byte-level debugging
Base5858NoYesNo (removed 0, O, l, I)Bitcoin addresses, IPFS CIDv0
Base6262NoYesMinor (0/O, l/I present)Short IDs, URL slugs, session tokens
Base6464Yes (=)No (needs Base64url variant)NoBinary data transport, JWT, data URIs

Base62 sits in a sweet spot: larger alphabet than Base58 (so shorter output) while still being completely URL-safe with no padding. Compare Base62 to Base58 encoder side-by-side — for the same integer input, Base62 always produces a string that is equal in length or one character shorter.

Integer to Base62: The Algorithm

Encoding an integer to Base62 is the standard positional-notation conversion algorithm, exactly like converting a decimal number to hexadecimal but with base 62.

const ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

function encodeBase62(n) {
  if (n === 0) return '0';
  let result = '';
  while (n > 0) {
    result = ALPHABET[n % 62] + result;
    n = Math.floor(n / 62);
  }
  return result;
}

// Examples
console.log(encodeBase62(0));          // "0"
console.log(encodeBase62(61));         // "z"
console.log(encodeBase62(62));         // "10"
console.log(encodeBase62(3844));       // "100"  (62 * 62)
console.log(encodeBase62(125000));     // "WXo"
console.log(encodeBase62(1000000000)); // "15FTGg"

Each iteration takes the remainder of dividing by 62 — that remainder is the next digit (least significant first, so we prepend). Once the quotient reaches zero we are done. The result grows logarithmically: every additional character multiplies the representable range by 62, so six Base62 characters cover over 56 billion values.

Decoding Base62: Horner's Method

Decoding is the reverse: iterate left to right, multiply the running total by 62, then add the value of the current character. This is Horner's method — the same technique used to evaluate polynomials and parse decimal strings.

function decodeBase62(str) {
  let result = 0;
  for (const char of str) {
    const value = ALPHABET.indexOf(char);
    if (value === -1) throw new Error('Invalid Base62 character: ' + char);
    result = result * 62 + value;
  }
  return result;
}

// Round-trip check
const id = 125000;
const encoded = encodeBase62(id);   // "WXo"
const decoded = decodeBase62(encoded); // 125000
console.log(decoded === id);           // true

For performance-sensitive code, replace ALPHABET.indexOf(char) with a lookup table built once at startup — a plain object or a Map from character to integer value brings decode time from O(62) per character down to O(1).

URL Shorteners: Base62 in Practice

The canonical real-world application of Base62 is the URL shortener. The architecture is straightforward:

  1. A user submits a long URL. The service inserts it into a database table and receives an auto-increment integer ID — say, 8743523.
  2. The service encodes that ID with Base62: encodeBase62(8743523) "Jk5F".
  3. The short URL becomes https://example.com/Jk5F. When visited, the service decodes "Jk5F" back to 8743523, looks up that row, and redirects.

A 6-character Base62 string covers 62⁶ = 56,800,235,584 values — enough for tens of billions of links. bit.ly, TinyURL, and YouTube video IDs all use this pattern (YouTube uses a Base64url variant; bit.ly uses Base62).

The Sequential ID Risk

One important caveat: because Base62 is a pure mathematical encoding, sequential database IDs produce sequential Base62 slugs. An attacker can enumerate all your shortened URLs by simply incrementing the slug. For most URL shorteners this is acceptable — the links are meant to be shared publicly. But for private links (password reset tokens, invite codes, document share links) sequential IDs are a serious vulnerability.

Common mitigations include:

  • Random IDs: Generate a cryptographically random 6–8 byte value and encode it with Base62 instead of encoding a sequential integer. Check for collisions in the database.
  • Hashids / Sqids: Libraries that encode integers to non-sequential, non-enumerable slugs while remaining reversible. They use a secret salt to shuffle the output.
  • UUID + truncation: Generate a UUID, take the first 8–10 characters. Not collision-free but practical at moderate scale.

If guessability is a security concern, treat the Base62 slug as an opaque token, not a reversible encoding of a sequential ID.

When to Use Base62

Base62 is the right tool when you need a compact, URL-safe, purely alphanumeric string derived from an integer. It is the wrong tool when you need to encode arbitrary binary data (use Base64), when human transcription matters and ambiguous characters are a concern (use Base58 — see also the Base58 Encoding guide), or when you need case-insensitive identifiers (use Base32).

For everything from URL shorteners to session tokens to auto-generated slugs, Base62 delivers the best combination of compactness, URL safety, and zero-dependency simplicity — the entire encoder fits in 10 lines of JavaScript with no external libraries. Use the Base62 encoder/decoder to convert values in your browser instantly.


Convert integers and strings to Base62 and back directly in your browser — no installation, no server, no data leaving your machine — with the Base62 encoder/decoder.