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

Как я могу сгенерировать GUID для строки?

У меня возникла проблема с созданием GUID для строки - например:

Guid g = New Guid("Mehar");

Как я могу вычислить GUID для "Mehar"? Я получаю исключение.

4b9b3361

Ответ 1

Довольно старая ветка, но так мы решили эту проблему:

Поскольку Guid из.NET Framework имеет произвольные 16 байтов или, соответственно, 128 битов, вы можете вычислить Guid из произвольных строк, применив к строке любую хэш-функцию, которая генерирует 16-байтовый хэш, и затем передайте результат в конструктор Guid.

Мы решили использовать хеш-функцию MD5, и пример кода может выглядеть так:

string input = "asdfasdf";
using (MD5 md5 = MD5.Create())
{
    byte[] hash = md5.ComputeHash(Encoding.Default.GetBytes(input));
    Guid result = new Guid(hash);
}

Обратите внимание, что у этого поколения Guid есть несколько недостатков, поскольку оно зависит от качества хэш-функции! Если ваша хеш-функция генерирует равные хеш-значения для большого количества строк, которые вы используете, это повлияет на поведение вашего программного обеспечения.

Вот список самых популярных хеш-функций, которые генерируют 128-битный дайджест:

  • RIPEMD (вероятность столкновения: 2 ^ 18)
  • MD4 (вероятность столкновения: точно)
  • MD5 (вероятность столкновения: 2 ^ 20,96)

Обратите внимание, что можно использовать и другие хеш-функции, которые генерируют большие дайджесты и просто усекают их. Поэтому может быть разумно использовать более новую хэш-функцию. Чтобы перечислить некоторые:

  • SHA-1
  • SHA-2
  • SHA-3

Сегодня (август 2013 г.) 160-битный хэш SHA1 можно считать хорошим выбором.

Ответ 2

Я уверен, что вы путаете System.Guid с желанием хеша (скажем, SHA-256) данной строки.

Обратите внимание, что при выборе криптографически безопасного алгоритма хэширования MD5, SHA0 и SHA1 все обычно считаются мертвыми. SHA2 и все еще пригодны для использования.

Ответ 3

То, что вы ищете, вероятно, создает UUID с версией 3 или 5, которые являются UUID с именами. (рекомендуется версия 5). Я не думаю, что платформа .NET поддерживает его. См. http://en.wikipedia.org/wiki/Universally_Unique_Identifier

Я сделал несколько поисковых запросов Google, чтобы узнать, могу ли я найти что-то в Win32 API, но ничего не получилось. Тем не менее, я уверен, что в .NET Framework какая-то реализация скрыта где-то, потому что, насколько мне известно, при создании COM-объекта в .NET и вы не предоставляете явный GUID, тогда .NET framework генерирует имя основанный на UUID для создания четко определенных идентификаторов ClassID и InterfaceID, то есть UUID, которые не меняются при каждом повторном компиляции (например, VB6). Но это, вероятно, скрыто, поэтому, я думаю, вам нужно реализовать алгоритм самостоятельно. К счастью,.NET обеспечивает как алгоритм MD5, так и SHA1, поэтому я не думаю, что внедрение U3ID версии 3 и версии 5 должно быть слишком сложным.

Ответ 4

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

То, что вы ищете, называется хэш-функцией. (например: MD5)

Ответ 5

Я думаю, что у вас есть непонимание того, что на самом деле существует. Не существует представления Guid строки, такой как "Mehar".

Причина перегрузки new Guid(String s) заключается в том, что вы можете создать указатель из типичного строкового представления одного, например, "00000000-0000-0000-0000000000000000".

См. статью wiki для получения дополнительной информации о том, что такое Guid.

http://en.wikipedia.org/wiki/Globally_Unique_Identifier

Ответ 6

В целом существует несколько способов сделать универсально уникальный идентификатор (UUID RFC 4122, GUID a.k.a.). Мы могли бы взять эти четыре из Python и сделать на С# что-то похожее:

uuid.uuid1([node[, clock_seq]])

Сгенерировать UUID из идентификатора хоста, порядкового номера и текущего времени. Если node не задано, getnode() используется для получения аппаратного обеспечения адрес. Если указано clock_seq, оно используется как порядковый номер; в противном случае выбирается случайный 14-разрядный порядковый номер.

uuid.uuid3(namespace, name)

Создайте UUID на основе хеша MD5 идентификатора пространства имен (который является UUID) и имени (которое является строкой).

uuid.uuid4()

Создайте случайный UUID.

uuid.uuid5(namespace, name)

Создайте UUID на основе хэша SHA-1 идентификатора пространства имен (который является UUID) и имени (которое является строкой).

Итак, если вам нужен идентификатор строки в качестве объекта, а не идентификатор значения, вы должны отменить свой частный UUID с заданной строкой, Ваш частный UUID генерирует один раз с помощью uuid1, а затем использует его как пространство имен для uuid3 или uuid5.

Эти варианты и версии описаны в Википедии Universally_unique_identifier # Варианты_и_версии

Ответ 7

Если целью op является создание UUID (Guid) из хеша строки какого-либо типа (MD5, SHA-1, et.c.), я нашел этот очень похожий вопрос с этим замечательным ответом:

fooobar.com/questions/69596/...

Он имеет ссылку на github-фрагмент, основанный на RFC 4122 §4.3, который создаст Guid из строки и пространства имен (которое вы можете выбрать для себя, чтобы гарантировать от коллизий из внешних сред).

Прямая ссылка на фрагмент: https://github.com/LogosBible/Logos.Utility/blob/master/src/Logos.Utility/GuidUtility.cs

Ответ 8

Вот мой собственный подход, я намеренно использую String для шестнадцатеричного дампа, если это возможно - визуально его можно увидеть по крайней мере, насколько велика строка, а при необходимости - декодируется с использованием некоторого онлайн-конвертера. Но если строка слишком длинная (более 16 байт), то с помощью sha-1 вычислять хэш и генерировать guid из него.

/// <summary>
/// Generates Guid based on String. Key assumption for this algorithm is that name is unique (across where it it being used)
/// and if name byte length is less than 16 - it will be fetched directly into guid, if over 16 bytes - then we compute sha-1
/// hash from string and then pass it to guid.
/// </summary>
/// <param name="name">Unique name which is unique across where this guid will be used.</param>
/// <returns>For example "{706C7567-696E-7300-0000-000000000000}" for "plugins"</returns>
static public String GenerateGuid(String name)
{
    byte[] buf = Encoding.UTF8.GetBytes(name);
    byte[] guid = new byte[16];
    if (buf.Length < 16)
    {
        Array.Copy(buf, guid, buf.Length);
    }
    else
    {
        using (SHA1 sha1 = SHA1.Create())
        {
            byte[] hash = sha1.ComputeHash(buf);
            // Hash is 20 bytes, but we need 16. We loose some of "uniqueness", but I doubt it will be fatal
            Array.Copy(hash, guid, 16);
        }
    }

    // Don't use Guid constructor, it tends to swap bytes. We want to preserve original string as hex dump.
    String guidS = "{" + String.Format("{0:X2}{1:X2}{2:X2}{3:X2}-{4:X2}{5:X2}-{6:X2}{7:X2}-{8:X2}{9:X2}-{10:X2}{11:X2}{12:X2}{13:X2}{14:X2}{15:X2}", 
        guid[0], guid[1], guid[2], guid[3], guid[4], guid[5], guid[6], guid[7], guid[8], guid[9], guid[10], guid[11], guid[12], guid[13], guid[14], guid[15]) + "}";

    return guidS;
}

Ответ 9

Вы используете статический метод NewGuid() для создания Guids, I.E., Guid g = Guid.NewGuid(); или string s = Guid.NewGuid().ToString()'

Ответ 10

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

Если вам нужна такая привязка, сохраните подсказки в словаре и сначала проверьте наличие существующего guid прежде, чем создать новый.