Как пользоваться конвертером Base36
- Введите текст в поле Ввод · Текст. Байты текста в UTF-8 кодируются в Base36, и результат появляется в поле Результат · Base36.
- Выберите строчные или ПРОПИСНЫЕ в опции Регистр под результатом. Оба варианта декодируются одинаково.
- Чтобы перевести число, выберите в меню Из вариант Целое (большое число) и введите десятичное значение. Если меняли меню В, верните его на Base36.
- Чтобы декодировать, нажмите Base36 → Текст в переключателе направления или выберите в меню В вариант Целое (большое число), чтобы получить десятичное число.
Base36 в десятичное и обратно
Base36 считает цифрами 0–9, а затем буквами a–z, так что a равно 10, а z – 35. Каждый разряд в 36 раз весомее соседнего справа:
| Base36 | Десятичное | Примечание |
|---|---|---|
z | 35 | Наибольшая одиночная цифра |
10 | 36 | |
zz | 1295 | 35 × 36 + 35 |
1000 | 46656 | 36³ |
21i3v9 | 123456789 | |
2gosa7pa2gv | 9007199254740991 | Number.MAX_SAFE_INTEGER в JavaScript |
3w5e11264sgsf | 18446744073709551615 | 2^64 − 1 |
Конвертер работает с BigInt, поэтому 64- и 128-битные значения получаются точными. Предел ввода (64 КБ) намного больше любого идентификатора.
Где используется Base36
Base36 подходит для идентификаторов, которые должны быть короткими и переживать системы, меняющие регистр: URL, которые некоторые программы приводят к нижнему регистру, файловые системы без учёта регистра, коды, которые диктуют вслух или набирают с бумаги. Пример – идентификаторы постов и комментариев на Reddit. Помогает и то, что большинство языков программирования читают числа в Base36 без библиотек.
Нечувствительность к регистру стоит Base36 части плотности. 16 случайных байт занимают 24 или 25 символов в Base36, 21 или 22 в Base62 и 32 в hex. Base62 короче, но чувствителен к регистру, а Base32 тоже не зависит от регистра, но жёстко делит данные на 5-битные группы и добавляет дополнение.
Текст, байты и ведущие нули
Текст и другие байты конвертер читает как одно большое число в порядке big-endian и записывает это число по основанию 36. Hello состоит из байтов 48 65 6c 6c 6f, то есть из числа 310939249775, а в Base36 это 3yud78mn. В чистом числе ведущие нулевые байты пропали бы, поэтому каждый из них записывается цифрой 0: байты 00 0a кодируются в 0a.
У ввода Целое (большое число) проблемы с ведущими нулями нет: у десятичного числа нет ведущих нулевых байтов, которые можно потерять.
Base36 в JavaScript и Python
Оба языка переводят числа встроенными средствами:
(255).toString(36); // '73'
parseInt("73", 36); // 255
(2n ** 64n - 1n).toString(36) // '3w5e11264sgsf'
BigInt умеет печатать по основанию 36, но парсера для него нет, а parseInt теряет точность после 2^53. Выручает короткий цикл:
function parseBase36(s) {
let n = 0n;
for (const ch of s.toLowerCase()) n = n * 36n + BigInt(parseInt(ch, 36));
return n;
}
parseBase36("3w5e11264sgsf"); // 18446744073709551615n
int() в Python принимает основание и работает с числами любого размера: int("3w5e11264sgsf", 36) возвращает 18446744073709551615. Встроенной функции для обратного направления нет; её заменяет цикл с divmod и алфавитом 0123456789abcdefghijklmnopqrstuvwxyz. Остальные приёмы есть на страницах JavaScript и Python.
Типичные проблемы
- Ошибка на
-,_или пробеле внутри значения. В Base36 есть только цифры и буквы. Уберите разделители или разбейте значение по ним, если они разделяют несколько идентификаторов. - Декодированный текст выглядит как мусор. Скорее всего, строка была числовым идентификатором, а не закодированным текстом. Выберите в меню В вариант Целое (большое число), чтобы увидеть её как число.
- Небольшие расхождения в последних цифрах в таблице или JSON. Где-то по пути число прошло через double. Храните большие идентификаторы строками на всём пути.
Вопросы и ответы
Как перевести Base36 в десятичное число?
Выберите в меню Из вариант Base36, в меню В – Целое (большое число) и вставьте значение Base36. zz даёт 1295, а 3w5e11264sgsf – 18446744073709551615, наибольшее беззнаковое 64-битное число.
Важен ли регистр в Base36?
Нет. Заглавные и строчные буквы имеют одно и то же значение, поэтому и ZZ, и zz равны 1295. Из распространённых кодировок, которые переживают смену регистра, Base36 самая плотная.
Почему parseInt в JavaScript даёт другое число?
parseInt(s, 36) возвращает double, а он точен только до 2^53. parseInt("3w5e11264sgsf", 36) возвращает 18446744073709552000, то есть ошибается на 385. Разбирайте в BigInt, как показано на этой странице.
Почему Base36 от Hello не равен parseInt('Hello', 36)?
Кодировщик превращает пять байт текста в число и записывает его по основанию 36 (3yud78mn). parseInt же читает буквы H-e-l-l-o как цифры Base36 и получает 29234652.