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

YouTube-подобный GUID

Возможно ли генерировать короткий GUID, как на YouTube (N7Et6c9nL9w)?

Как это можно сделать? Я хочу использовать его в веб-приложении.

4b9b3361

Ответ 1

Вы можете использовать Base64:

string base64Guid = Convert.ToBase64String(Guid.NewGuid().ToByteArray());

Это создает строку типа E1HKfn68Pkms5zsZsvKONw==. Поскольку GUID всегда 128 бит, вы можете опустить ==, который, как вы знаете, всегда будет присутствовать в конце, и это даст вам строку с 22 символами. Это не так сложно, как YouTube.

Ответ 2

9 символов - это не руководство. Учитывая это, вы можете использовать шестнадцатеричное представление int, которое дает вам строку 8 char.

Обновление 1: Не знаю, почему выше получилось нисходящее, но для кого-то интересно:

Вы можете использовать идентификатор, который у вас уже есть. Также вы можете использовать .GetHashCode для разных простых типов, и там у вас есть другой int. Вы также можете использовать разные поля. И если вы входите в нее, вы можете даже использовать случайное число - эй, у вас гораздо больше 2.000.000.000 + возможных значений, если вы придерживаетесь положительных результатов;)

Ответ 3

Как упоминается в принятом ответе, он может создавать проблемы, если вы используете GUID в URL. Вот более полный ответ:

    public string ToShortString(Guid guid)
    {
        var base64Guid = Convert.ToBase64String(guid.ToByteArray());

        // Replace URL unfriendly characters with better ones
        base64Guid = base64Guid.Replace('+', '-').Replace('/', '_');

        // Remove the trailing ==
        return base64Guid.Substring(0, base64Guid.Length - 2);
    }

    public Guid FromShortString(string str)
    {
        str = str.Replace('_', '/').Replace('-', '+');
        var byteArray = Convert.FromBase64String(str + "==");
        return new Guid(byteArray);
    }

Использование:

        var guid = Guid.NewGuid();
        var shortStr = ToShortString(guid);
        // shortStr will look something like 2LP8GcHr-EC4D__QTizUWw
        var guid2 = FromShortString(shortStr);
        Assert.AreEqual(guid, guid2);

Ответ 4

Как уже упоминалось, YouTube VideoId не является технически GUID, поскольку он не является по своей сути уникальным.

По Wikipedia:

Общее количество уникальных ключей - 2 128 или 3.4 × 10 38. Это число так что вероятность того же числа генерируется случайным образом дважды является незначительным.

Уникальность YouTube VideoId поддерживается их алгоритмом генерации.

Вы можете либо написать свой собственный алгоритм, либо использовать какой-то генератор случайных строк и использовать ограничение UNIQUE CONSTRAINT в SQL, чтобы обеспечить его уникальность.

Сначала создайте UNIQUE CONSTRAINT в своей базе данных:

ALTER TABLE MyTable
ADD CONSTRAINT UniqueUrlId
UNIQUE (UrlId);

Затем, например, сгенерируйте случайную строку (из philipproplesch answer):

string shortUrl = System.Web.Security.Membership.GeneratePassword(11, 0);

Если сгенерированный UrlId достаточно случайный и достаточно длинный, вам редко приходится сталкиваться с тем исключением, которое возникает, когда SQL встречает дубликат UrlId. В таком случае вы можете легко справиться с этим исключением в своем веб-приложении.

Ответ 5

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

Ответ 6

Это может быть не лучшее решение, но вы можете сделать что-то вроде этого:

string shortUrl = System.Web.Security.Membership.GeneratePassword(11, 0);

Ответ 7

Этот идентификатор, вероятно, не является глобально уникальным. GUID должен быть глобально уникальным, так как он включает элементы, которые не должны встречаться в другом месте (MAC-адрес машины, генерирующей идентификатор, время создания идентификатора и т.д.).

Если вам нужен идентификатор, который является уникальным в вашем приложении, используйте фонтан числа - возможно, кодируя значение в виде шестнадцатеричного числа. Каждый раз, когда вам нужен идентификатор, возьмите его из фонтана.

Если у вас есть несколько серверов, выделяющих идентификаторы, вы можете захватить ряд чисел (несколько десятков или тысяч в зависимости от того, как быстро вы выделяете идентификаторы), и это должно выполнять эту работу. 8-значный шестнадцатеричный номер даст вам 4 миллиарда идентификаторов, но ваш первый идентификатор будет намного короче.

Ответ 8

Это не GUID

Позвольте мне перейти со следующим

Он использует TotalMilliseconds из EPOCH и действительный набор символов.

Это не будет глобально уникальным, но уникальным для случая, когда оно определяет

public string YoutubeLikeId()
{
    Thread.Sleep(1);//make everything unique while looping
    long ticks = (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1,0,0,0,0))).TotalMilliseconds;//EPOCH
    char[] baseChars = new char[] { '0','1','2','3','4','5','6','7','8','9',
            'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
            'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x'};

    int i = 32;
    char[] buffer = new char[i];
    int targetBase= baseChars.Length;

    do
    {
        buffer[--i] = baseChars[ticks % targetBase];
        ticks = ticks / targetBase;
    }
    while (ticks > 0);

    char[] result = new char[32 - i];
    Array.Copy(buffer, i, result, 0, 32 - i);

    return new string(result);
}

На выходе придет что-то вроде

XOTgBsu
XOTgBtB
XOTgBtR
XOTgBtg
XOTgBtw
XOTgBuE

Обновление: то же самое можно сделать из Guid как

var guid = Guid.NewGuid(); 
guid.ToString("N");
guid.ToString("N").Substring(0,8);
guid.ToString("N").Substring(8,4);
guid.ToString("N").Substring(12,4);
guid.ToString("N").Substring(16,4);
guid.ToString("N").Substring(20,12);

Для Guid ecd65132-ab5a-4587-87b8-b875e2fe0f35 он будет ecd65132-ab5a-4587-87b8-b875e2fe0f35 на куски как ecd65132, ab5a, 4587, 87b8, b875e2fe0f35

но я не могу гарантировать, что он всегда будет уникальным.

Обновление 2: Существует также проект под названием ShortGuid, чтобы получить дружественный для URL GUID который можно преобразовать из/в обычный Guid