В нашем приложении мы создаем XML-файлы с атрибутом, который имеет значение Гуида. Это значение должно было быть последовательным между обновлениями файла. Таким образом, даже если все остальное в изменениях файла, значение гуида для атрибута должно остаться тем же.
Одно очевидное решение состояло в том, чтобы создать статический словарь с именем файла и Гуидами, которые будут использоваться для них. Затем каждый раз, когда мы генерируем файл, мы ищем словарь для имени файла и используем соответствующий гуид. Но это не выполнимо, потому что мы могли бы масштабироваться к 100's файлов и не хотели вести большой список гуидов.
Таким образом, другой подход должен был сделать Гуид тем же на основе пути файла. Так как наши пути к файлам и структура каталога приложения уникальны, Гуид должен быть уникальным для того пути. Так каждый раз, когда мы выполняем обновление, файл получает тот же гуид на основе своего пути. Я нашел один прохладный способ генерировать такие 'Детерминированные Гуиды' (Спасибо Elton Stoneman). Это в основном делает это:
private Guid GetDeterministicGuid(string input)
{
//use MD5 hash to get a 16-byte hash of the string:
MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
byte[] inputBytes = Encoding.Default.GetBytes(input);
byte[] hashBytes = provider.ComputeHash(inputBytes);
//generate a guid from the hash:
Guid hashGuid = new Guid(hashBytes);
return hashGuid;
}
Так, учитывая строку, Гуид всегда будет тем же.
Есть ли какие-либо другие подходы или рекомендуемые пути к выполнению этого? Каковы профессионалы или недостатки того метода?
MD5 слабый, я считаю, что вы можете сделать то же самое с SHA-1 и получить лучшие результаты.
Кстати, это личное мнение, но использование хэша md5 в качестве GUID не делает его хорошим GUID. GUID по самой своей природе недетерминированы. это похоже на чит. Почему бы просто не назвать вещи своими именами и просто сказать, что это строковый хэш ввода. вы можете сделать это, используя эту строку, а не новую строку guid:
string stringHash = BitConverter.ToString(hashBytes)
Вам необходимо различать экземпляры класса Guid
и идентификаторы, которые являются глобально уникальными. «Детерминированный гид» на самом деле является хешем (о чем свидетельствует ваш звонок в provider.ComputeHash
). Хэши имеют гораздо более высокий шанс коллизий (две разные строки создают один и тот же хеш), чем Guid, созданный с помощью Guid.NewGuid
.
Таким образом, проблема с вашим подходом состоит в том, что вы должны быть согласны с возможностью того, что два разных пути будут давать один и тот же GUID. Если вам нужен идентификатор, уникальный для любой заданной строки пути, то проще всего просто использовать строку . Если вам нужно, чтобы строка была скрыта от пользователей, зашифруйте ее - вы можете использовать ROT13 или что-то более мощное ...
Попытка втиснуть что-то, что не является чистым GUID, в тип данных GUID может привести к проблемам с обслуживанием в будущем ...
Как упоминает Роб, ваш метод не генерирует UUID, он генерирует хэш, который выглядит как UUID.
RFC 4122 по UUID специально допускает детерминированные (основанные на имени) UUID - версии 3 и 5 используют md5 и SHA1 (соответственно).Большинство людей, вероятно, знакомы с версией 4, которая случайна. Википедия дает хороший обзор версий. (Обратите внимание, что использование слова «версия» здесь, кажется, описывает «тип» UUID - версия 5 не заменяет версию 4).
Кажется, существует несколько библиотек для генерации UUID версии 3/5, включая модуль uuid python , boost.uuid (C ++) и OSSP UUID . (Я не искал .net)