Подтвердить что ты не робот

Создание человекочитаемых/пригодных для использования, коротких, но уникальных идентификаторов

  • Необходимо обрабатывать > 1000, но < 10000 новых записей в день

  • Нельзя использовать идентификаторы GUID/UUID, номера автоматического увеличения и т.д.

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

  • Хотелось бы повторно использовать существующие, хорошо известные algos, если они доступны

Что-нибудь там?

4b9b3361

Ответ 1

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

Показатели уникальности базы 62

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

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

Базовые 36 показателей уникальности

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

7 символов дадут вам 36 ^ 7 уникальных идентификаторов = 78 364 164 000 (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

Ответ 2

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

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

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

Ответ 3

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

Короче:

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

Недостатки:

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

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

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

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

Вот проекты:

suid - Распределенные услуги - уникальные идентификаторы, которые являются короткими и приятными

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

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

Ответ 4

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