Base36: the largest common alphanumeric base
Base36 is a positional numeral system using all ten decimal digits plus all 26 letters of the Latin alphabet — 0 through 9, then A through Z — giving the largest base achievable using only the characters commonly available on a keyboard without resorting to punctuation or case-sensitivity. Like hex-to-decimal conversion, hex-to-base36 conversion goes through ordinary weighted-sum and repeated-division arithmetic, since 36 isn't a power of 2 and shares no bit-level shortcut with hex, binary, or octal.
Why base36 is used for short identifiers
The main practical reason to reach for base36 is compactness for identifiers. A base36 digit carries more information than a decimal digit (36 possible values instead of 10) or a hex digit (36 instead of 16), so a large integer — a database row ID, a timestamp, a hash truncated to a manageable size — takes noticeably fewer characters to write in base36 than in decimal. URL shorteners, order and invoice numbers, and session or object identifiers frequently encode an incrementing integer in base36 for exactly this reason: it keeps IDs short and still readable and typeable by a person, which a raw Base64-style byte encoding (with mixed case and punctuation) is less suited for in a URL path segment.
A worked example
Take the hex value 0x3E8, equal to 1000 in decimal. Converting via repeated division by 36: 1000 ÷ 36 = 27 remainder 28; 27 ÷ 36 = 0 remainder 27. In base36, 27 is the letter R (A=10, so R is the 18th letter, 10+17=27) and 28 is S. Reading the remainders from last to first gives RS — so 0x3E8 is RS in base36. Checking the reverse direction: (27 × 36¹) + (28 × 36⁰) = 972 + 28 = 1000, confirming the result.
Case sensitivity in base36
Base36 is conventionally treated as case-insensitive — the letters represent digit values, not distinct characters, so rs and RS represent the same number. This tool accepts either case on input and produces uppercase on output, which is the more common convention in practice (matching hex's usual uppercase display), though some systems that generate base36 identifiers use lowercase instead. Because case doesn't carry information in either convention, mixing the two when comparing or storing identifiers is safe as long as comparisons are also done case-insensitively.
Base36 in practice: base()/parseInt and similar utilities
Many programming languages expose base36 conversion directly as a built-in feature rather than requiring a dedicated library, which is part of why it's a common choice for lightweight ID generation. JavaScript'sNumber.prototype.toString(36) and parseInt(str, 36), Python's built-inint(str, 36), and Ruby's to_s(36) all convert directly between an integer and its base36 representation without any external dependency. That native support, combined with base36 needing no padding or special-character handling the way Base32 and Base64 do, makes it a convenient default whenever a short, roughly-numeric-looking identifier is needed and there's no requirement to follow a specific external standard.
A timestamp is a common input for this pattern. A Unix timestamp in the billions of seconds becomes a much shorter base36 string, and because base36 preserves ordering (a larger number always produces a "larger" base36 string under standard string comparison, as long as strings are compared with equal padding), base36-encoded timestamps still sort correctly as identifiers, which is a property Base64 output does not reliably preserve.
Base36 versus Base62
A closely related but distinct scheme, base62, extends base36 by treating uppercase and lowercase letters as separate digit values (10 digits + 26 uppercase + 26 lowercase = 62), producing even shorter identifiers for the same numeric value at the cost of case sensitivity. Base62 is common in URL-shortening services and some database ID schemes for that reason. It isn't implemented as a separate tool here because, unlike Base16, Base32, and Base64, base62 has no equivalent formal standard (no RFC defines it) and different implementations sometimes order or select their digit alphabet differently — a base36 value, in contrast, has one unambiguous conventional digit ordering.
Because of that ambiguity, code that needs to interoperate across systems is often safer sticking with base36 or hex, both of which have a single agreed-upon digit ordering, rather than a bespoke base62 scheme whose alphabet order has to be checked against the specific library or service that produced it.