How to use the Base36 converter
- Type text into Input · Text. Its UTF-8 bytes are encoded and the result appears in Output · Base36.
- Pick lowercase or UPPERCASE under Case below the output. Both decode the same way.
- To convert a number, set From to Integer (big number) and type the decimal value. Set To back to Base36 if you changed it.
- To decode, click Base36 → Text in the direction toggle, or set To to Integer (big number) to get decimal.
Base36 to decimal and back
Base36 counts with 0–9 and then a–z, so a is 10 and z is 35. Each position is worth 36 times the one to its right:
| Base36 | Decimal | Note |
|---|---|---|
z | 35 | The largest single digit |
10 | 36 | |
zz | 1295 | 35 × 36 + 35 |
1000 | 46656 | 36³ |
21i3v9 | 123456789 | |
2gosa7pa2gv | 9007199254740991 | Number.MAX_SAFE_INTEGER in JavaScript |
3w5e11264sgsf | 18446744073709551615 | 2^64 − 1 |
The converter works with BigInt, so 64-bit and 128-bit values come out exact. Its limit is 64 KB of input, far more than any ID.
Where Base36 is used
Base36 suits identifiers that should be short and must survive systems that change case: URLs that some software lowercases, case-insensitive file systems, and codes read aloud or typed from paper. Reddit’s post and comment IDs are an example. Most programming languages can also read Base36 numbers without a library.
Compared with the alternatives, Base36 gives up some density for case-insensitivity. 16 random bytes are 24 or 25 Base36 characters, 21 or 22 in Base62 and 32 in hex. Base62 is shorter but case-sensitive, and Base32 is case-insensitive too but fixes the alphabet into 5-bit groups and adds padding.
Text, bytes and leading zeros
For text and other bytes, the converter reads the input as one big-endian number and writes that number in base 36. Hello is the bytes 48 65 6c 6c 6f, the number 310939249775, and in Base36 3yud78mn. Leading zero bytes would vanish in a pure number, so each one is written as a 0 digit: the bytes 00 0a encode as 0a.
An Integer input has no leading-zero problem, because a decimal number has no leading zero bytes to lose.
Base36 in JavaScript and Python
Both languages convert numbers natively:
(255).toString(36); // '73'
parseInt("73", 36); // 255
(2n ** 64n - 1n).toString(36) // '3w5e11264sgsf'
BigInt can print in base 36 but has no parser for it, and parseInt loses precision past 2^53. A short loop fixes that:
function parseBase36(s) {
let n = 0n;
for (const ch of s.toLowerCase()) n = n * 36n + BigInt(parseInt(ch, 36));
return n;
}
parseBase36("3w5e11264sgsf"); // 18446744073709551615n
Python’s int() takes a base and works at any size: int("3w5e11264sgsf", 36) returns 18446744073709551615. There is no built-in for the other direction; a divmod loop with the alphabet 0123456789abcdefghijklmnopqrstuvwxyz does it. More patterns are on the JavaScript and Python pages.
Common problems
- Error at a
-,_or space inside the value. Base36 has only digits and letters. Strip separators, or split the value at them if they separate several IDs. - The decoded text is garbage. The string was probably a numeric ID, not encoded text. Set To to Integer (big number) to see it as a number.
- Small differences in the last digits in a spreadsheet or JSON. The number went through a double somewhere. Keep large IDs as strings end to end.
FAQ
How do I convert Base36 to decimal?
Set From to Base36 and To to Integer (big number), then paste the Base36 value. zz gives 1295 and 3w5e11264sgsf gives 18446744073709551615, the largest unsigned 64-bit number.
Is Base36 case-sensitive?
No. Upper and lower case letters have the same value, so ZZ and zz are both 1295. That makes Base36 the densest common encoding that survives case changes.
Why does JavaScript parseInt give a different number?
parseInt(s, 36) returns a double, which is exact only up to 2^53. parseInt("3w5e11264sgsf", 36) returns 18446744073709552000, off by 385. Parse into a BigInt instead, as shown on this page.
Why is the Base36 of Hello not the same as parseInt('Hello', 36)?
The encoder turns the five bytes of the text into a number and writes that in base 36 (3yud78mn). parseInt instead reads the letters H-e-l-l-o as Base36 digits, giving 29234652.