Создание удобных для чтения / использования коротких, но уникальных идентификаторов - PullRequest
71 голосов
/ 03 марта 2012
  • Требуется обработать> 1000, но <10000 новых записей в день </p>

  • Невозможно использовать GUID / UUID, числа с автоматическим приращением и т. Д.

  • В идеале должно быть длиной 5 или 6 символов, конечно, может быть альфа-каналом

  • Хотелось бы повторно использовать существующие, известные алгоритмы, если таковые имеются

Что-нибудь есть?

Ответы [ 4 ]

95 голосов
/ 03 марта 2012

Base 62 используется tinyurl и bit.ly для сокращенных URL-адресов. Это хорошо понятный метод создания «уникальных», понятных человеку идентификаторов. Конечно, вам придется хранить созданные идентификаторы и проверять наличие дубликатов при создании, чтобы гарантировать уникальность. (см. Код внизу ответа)

База 62 показателей уникальности

5 символов в базе 62 дадут вам 62 ^ 5 уникальных идентификаторов = 916 132 832 (~ 1 миллиард) При 10 тыс. Идентификаторов в день вы будете в порядке на 91 тыс. + Дней

6 символов в базе 62 дадут вам 62 ^ 6 уникальных идентификаторов = 56 800 235 584 (56+ миллиардов) При 10 000 идентификаторов в день вы будете в порядке в течение 5 миллионов дней

Методы уникальности Base 36

6 символов дадут вам 36 ^ 6 уникальных идентификаторов = 2 176 782 336 (2+ миллиарда)

7 символов дадут вам 36 ^ 7 уникальных идентификаторов = 78 364 164 096 (78+ миллиардов)

Код:

public void TestRandomIdGenerator()
{
    // create five IDs of six, base 62 characters
    for (int i=0; i<5; i++) Console.WriteLine(RandomIdGenerator.GetBase62(6));

    // create five IDs of eight base 36 characters
    for (int i=0; i<5; i++) Console.WriteLine(RandomIdGenerator.GetBase36(8));
}

public static class RandomIdGenerator 
{
    private static char[] _base62chars = 
        "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
        .ToCharArray();

    private static Random _random = new Random();

    public static string GetBase62(int length) 
    {
        var sb = new StringBuilder(length);

        for (int i=0; i<length; i++) 
            sb.Append(_base62chars[_random.Next(62)]);

        return sb.ToString();
    }       

    public static string GetBase36(int length) 
    {
        var sb = new StringBuilder(length);

        for (int i=0; i<length; i++) 
            sb.Append(_base62chars[_random.Next(36)]);

        return sb.ToString();
    }
}

Выход:

z5KyMg
wd4SUp
uSzQtH
UPrGAT
UIf2IS

QCF9GNM5
0UV3TFSS
3MG91VKP
7NTRF10T
AJK3AJU7
14 голосов
/ 31 марта 2015

Я рекомендую http://hashids.org/, который преобразует любое число (например, DB ID) в строку (с использованием соли).

Позволяет декодировать эту строку обратно в число. Поэтому вам не нужно хранить его в базе данных.

Имеет библиотеки для JavaScript, Ruby, Python, Java, Scala, PHP, Perl, Swift, Clojure, Objective-C, C, C ++ 11, Go, Erlang, Lua, Elixir, ColdFusion, Groovy, Kotlin, Nim, VBA, CoffeeScript и для Node.js & .NET.

6 голосов
/ 10 июня 2015

У меня были те же требования, что и у ОП.Я просмотрел доступные библиотеки, но большинство из них основаны на случайности, и я не хотел этого.Я не мог найти ничего, что не было бы основано на случайных и все еще очень коротких ... Так что я закончил тем, что катал свой собственный, основанный на метод Flickr, использующий , но модифицированный, чтобы требовать меньшего количества координации и учитывать более длительные периодыне в сети.

Вкратце:

  • Центральный сервер выдает блоки идентификаторов, каждый из которых состоит из 32 идентификаторов
  • Локальный генератор идентификаторов поддерживает пул блоков идентификаторов для генерации идентификаторов каждыйраз один запрашивается.Когда пул заканчивается, он выбирает больше блоков ID с сервера, чтобы заполнить его снова.

Недостатки:

  • Требуется централизованная координация
  • Идентификаторыболее или менее предсказуемый (меньше, чем обычные идентификаторы БД, но они не случайные)

Преимущества

  • Пребывание в пределах 53 бит (максимальный размер Javascript / PHP для целых чисел))
  • очень короткие идентификаторы
  • в кодировке Base 36, так что люди могут легко читать, писать и произносить
  • ID могут генерироваться локально для оченьдолгое время, прежде чем снова потребуется связь с сервером (в зависимости от настроек пула)
  • Теоретически нет вероятности коллизий

Я опубликовал как библиотеку Javascript для клиентской стороны, так иреализация сервера Java EE.Внедрение серверов на других языках также должно быть простым.

Вот проекты:

suid - короткие идентификаторы распределенных услуг - короткиеand sweet

suid-server-java - Реализация suid-сервера для стека технологий Java EE.

Обе библиотеки доступны в рамках либеральной версии.Лицензия Creative Commons с открытым исходным кодом.Надеясь, что это может помочь кому-то еще искать короткие уникальные идентификаторы.

3 голосов
/ 24 февраля 2016

Я использовал base 36 , когда решил эту проблему для приложения, которое разрабатывал пару лет назад.Мне нужно было сгенерировать понятное человеку разумно уникальное число (в любом случае, в течение текущего календарного года).Я решил использовать время в миллисекундах с полуночи 1 января текущего года (чтобы метки времени могли дублироваться каждый год) и преобразовывать его в базовое число 36.Если разрабатываемая система сталкивалась с фатальной проблемой, она генерировала базовый номер 36 (7 символов), который отображался конечному пользователю через веб-интерфейс, который затем мог передать возникшую проблему (и номер) сотруднику службы технической поддержки (которыйможет затем использовать его, чтобы найти точку в журналах, где начиналась трассировка стека).Число типа 56af42g7 для пользователя бесконечно проще для чтения и передачи, чем отметка времени, например 2016-01-21T15: 34: 29.933-08: 00 , или случайный UUID, например 5f0d3e0c-da96-11e5-b5d2-0a1d41d68578 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...