Система генерации удобочитаемых идентификаторов: постулаты и алгоритм
В процессе разработки веб-приложений и корпоративных систем часто возникает задача присвоения каждому объекту уникального идентификатора. Традиционные числовые ID коротки, но неинформативны. GUID надёжны, но длинны и нечитаемы. Мы разработали систему генерации коротких (8 символов), произносимых, уникальных идентификаторов, которые:
- легко запоминаются и передаются по телефону;
- не содержат символов, похожих на цифры или друг на друга;
- имеют фиксированную длину и структуру;
- могут быть закодированы и декодированы без потери информации.
Постулаты системы
Мы ограничили алфавит, чтобы исключить неоднозначности и сделать идентификаторы максимально дружественными к человеку.
Алфавит согласных (12 букв)
Б, Г, Д, К, Л, М, Н, П, Р, С, Т, Ш
Все эти буквы имеют чёткое начертание, не путаются с цифрами (например, О и 0, З и 3) и друг с другом даже при небрежном почерке.
Алфавит гласных (4 буквы)
А, Е, И, У
Они легко произносятся, не имеют омографов среди цифр и дают широкий спектр сочетаний.
Базовый слог
Каждый слог состоит из одной согласной и одной гласной. Всего различных слогов: 12 × 4 = 48.
Структура идентификатора
Идентификатор строится из трёх слогов, разделённых дефисами:
СЛОГ1-СЛОГ2-СЛОГ3
Длина строки: 6 букв + 2 дефиса = 8 символов.
Мощность пространства
Общее количество возможных идентификаторов: 48³ = 110 592. Этого с избытком хватает для покрытия диапазона чисел от 0 до 32 767 (2¹⁵ – 1).
Биективность
Отображение «число → идентификатор» является взаимно однозначным на интервале [0, 32767]:
- каждому числу соответствует ровно один идентификатор;
- по идентификатору можно однозначно восстановить исходное число;
- коллизии исключены.
Алгоритм генерации
Вход: целое число N (0 ≤ N ≤ 32 767).
Выход: строка вида XX-XX-XX, где X — буква из согласных или гласных.
Шаг 1. Перевод в 48-ричную систему
Вычислим три цифры d₂ (старшая), d₁, d₀ (младшая) по основанию 48:
d₂ = floor(N / 2304) // 48² = 2304
r₁ = N mod 2304
d₁ = floor(r₁ / 48)
d₀ = r₁ mod 48
Все цифры находятся в диапазоне 0…47.
Шаг 2. Преобразование цифры в слог
СОГЛАСНЫЕ = ['Б', 'Г', 'Д', 'К', 'Л', 'М', 'Н', 'П', 'Р', 'С', 'Т', 'Ш']
ГЛАСНЫЕ = ['А', 'Е', 'И', 'У']
индекс_согласной = d // 4
индекс_гласной = d % 4
слог = СОГЛАСНЫЕ[индекс_согласной] + ГЛАСНЫЕ[индекс_гласной]
Шаг 3. Сборка идентификатора
идентификатор = слог(d₂) + "-" + слог(d₁) + "-" + слог(d₀)
Примеры выполнения
| N | Вычисления (d₂, d₁, d₀) | Слоги | Идентификатор |
|---|---|---|---|
| 0 | (0, 0, 0) | БА, БА, БА | БА-БА-БА |
| 1 | (0, 0, 1) | БА, БА, БЕ | БА-БА-БЕ |
| 48 | (0, 1, 0) | БА, БЕ, БА | БА-БЕ-БА |
| 2304 | (1, 0, 0) | БЕ, БА, БА | БЕ-БА-БА |
| 32767 | (14, 10, 31) | КИ, ДИ, ПУ | КИ-ДИ-ПУ |
Проверка для 32767: 14×2304 + 10×48 + 31 = 32256 + 480 + 31 = 32767 — верно.
Обратный алгоритм (декодирование)
Если необходимо из идентификатора получить исходное число N:
- Разбить строку по дефисам → три слога.
- Для каждого слога вычислить цифру:
позиция_согласной × 4 + позиция_гласной. - Вычислить
N = d₂ × 2304 + d₁ × 48 + d₀.
Реализация (псевдокод)
СОГЛАСНЫЕ = ['Б', 'Г', 'Д', 'К', 'Л', 'М', 'Н', 'П', 'Р', 'С', 'Т', 'Ш']
ГЛАСНЫЕ = ['А', 'Е', 'И', 'У']
def number_to_id(N):
if N < 0 or N > 32767:
raise ValueError('Число вне диапазона')
BASE = 48
BASE2 = BASE * BASE # 2304
d2 = N // BASE2
r1 = N % BASE2
d1 = r1 // BASE
d0 = r1 % BASE
def digit_to_syllable(d):
return СОГЛАСНЫЕ[d // 4] + ГЛАСНЫЕ[d % 4]
return f"{digit_to_syllable(d2)}-{digit_to_syllable(d1)}-{digit_to_syllable(d0)}"
# Пример
print(number_to_id(32767)) # "КИ-ДИ-ПУ"
Почему это работает
Наша система опирается на четыре ключевых постулата:
- Постулат полноты: 48³ > 32768, поэтому все числа имеют уникальное представление.
- Постулат отсутствия коллизий: преобразование «цифра → слог» инъективно, а 48-ричное представление единственно.
- Постулат удобства: выбранные буквы не вызывают путаницы при записи от руки.
- Постулат произносимости: каждый слог состоит из согласной и гласной, что позволяет диктовать по слогам.
Где мы это применяем
Данный механизм уже внедрён в систему управления заказами «Лекала» (проект в нашем портфолио). Вместо числовых номеров заказов мы показываем клиентам и менеджерам короткие идентификаторы, которые:
- удобно называть при звонке;
- легко вводить в поисковую строку;
- не требуют переключения раскладки клавиатуры;
- выглядят профессионально и запоминаются.
В будущем планируем использовать эту же методику для генерации номеров счетов, накладных и других документов.
Мы разработали простую, но элегантную систему генерации идентификаторов, которая сочетает математическую строгость и человеческую эргономику. Если вам тоже нужны короткие, произносимые и уникальные коды — смело берите наш алгоритм за основу.
По всем вопросам внедрения — пишите на avkostrubin@yandex.ru или через на сайте.