Base36 represents whole numbers using all ten digits and all twenty-six letters, giving a compact, case-insensitive, alphanumeric form. It is the encoding behind many short IDs and shortened-URL schemes, where fitting a big number into a few readable characters is the goal.
How it works
Encoding repeatedly divides the number by 36 and reads the remainders from last to first; decoding does the reverse with a positional sum:
digits = 0123456789abcdefghijklmnopqrstuvwxyz
encode: while n > 0 { prepend digits[n mod 36]; n = n div 36 }
decode: value = 0; for each char c { value = value*36 + index(c) }
All arithmetic is done with arbitrary-precision integers, so the conversion is exact even for numbers with hundreds of digits.
Example and tips
The decimal number 123456789 becomes 21i3v9 in base-36 — six characters
instead of nine. Decoding 21i3v9 returns 123456789, and decoding 21I3V9
gives the same result because letters are case-insensitive. Use base-36 when you
want short human-friendly identifiers; if you need to encode raw bytes or text
rather than an integer, reach for Base32 or Base64 instead.
When developers actually use base-36
Base-36 fills a specific niche: you need an integer to be human-readable, typeable, and compact, but you do not need it to be case-sensitive. A few common applications:
Short URL identifiers. A sequential database row ID like 987654321 encodes to gly57 in base-36 — five characters instead of nine, using only letters and digits. The case-insensitivity is a useful property here: users who type a URL by hand from memory can use any mixture of upper and lower case and still reach the right resource.
Invite codes and vouchers. Systems that generate one-time codes for referrals, discounts, or beta invites often use base-36 because the output is safe to read aloud over a phone call or read from a printed page without ambiguity about which character is which.
Order and invoice references. A business that assigns sequential order numbers can encode them as short base-36 strings for display on receipts (for example order 4f2a) while keeping the underlying integer as the primary key in the database.
Comparing base-36 to neighbouring encodings
| Encoding | Symbols | Case sensitive? | Characters needed for 2^32 |
|---|---|---|---|
| Decimal (base-10) | 0–9 | No | 10 |
| Hexadecimal (base-16) | 0–9, a–f | No (by convention) | 8 |
| Base-36 | 0–9, a–z | No | 7 |
| Base-62 | 0–9, a–z, A–Z | Yes | 6 |
| Base-64 | 0–9, a–z, A–Z, +, / | Yes + special chars | 6 |
Base-36 saves one character compared to hex and two compared to decimal, at no cost in readability — and it avoids the case-sensitivity requirement of base-62. If you are operating in an environment where upper and lower case are equivalent (a domain name, a case-insensitive filesystem path, a voice system), base-36 is often the right choice over base-62.
Large numbers and precision
The tool uses arbitrary-precision arithmetic. This matters for modern systems: database primary keys generated by distributed ID schemes (such as Snowflake IDs) are often 64-bit integers too large to represent exactly as a JavaScript number. Encoding and decoding via BigInt keeps the conversion exact to the last digit, which is important if the encoded value is also used as a database key.