W naszej aplikacji tworzymy pliki Xml z atrybutem o wartości Guid. Ta wartość musiała być spójna między aktualizacjami plików. Więc nawet jeśli wszystko inne w pliku się zmieni, wartość guid dla atrybutu powinna pozostać taka sama.
Jednym z oczywistych rozwiązań było utworzenie słownika statycznego z nazwą pliku i identyfikatorami Guid, które miały być dla nich używane. Następnie za każdym razem, gdy generujemy plik, szukamy w słowniku nazwy pliku i używamy odpowiedniego guidu. Ale to nie jest wykonalne, ponieważ możemy skalować do setek plików i nie chcieliśmy utrzymywać dużej listy poradników.
Więc innym podejściem było uczynienie Guid tym samym na podstawie ścieżki do pliku. Ponieważ nasze ścieżki plików i struktura katalogów aplikacji są unikalne, identyfikator Guid powinien być unikalny dla tej ścieżki. Tak więc za każdym razem, gdy uruchamiamy aktualizację, plik otrzymuje ten sam identyfikator guid na podstawie swojej ścieżki. Znalazłem fajny sposób na generowanie takich „ deterministycznych przewodników ” (dzięki Elton Stoneman). Zasadniczo robi to:
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;
}
Więc mając ciąg, Guid zawsze będzie taki sam.
Czy są jakieś inne podejścia lub zalecane sposoby, aby to zrobić? Jakie są wady i zalety tej metody?
Spowoduje to przekonwertowanie dowolnego ciągu na Guid bez konieczności importowania zewnętrznego zestawu.
Istnieją znacznie lepsze sposoby generowania unikatowego Guid, ale jest to sposób na konsekwentną aktualizację klucza danych ciągu do klucza danych Guid.
źródło
Jak wspomina Rob, twoja metoda nie generuje UUID, generuje hash, który wygląda jak UUID.
RFC 4122 na UUID szczególności pozwala deterministycznych (nazwa oparte) UUID - wersje 3 i 5 Zastosowanie MD5 i SHA1 (odpowiednio). Większość ludzi prawdopodobnie zna wersję 4, która jest przypadkowa. Wikipedia daje dobry przegląd wersji. (Zauważ, że użycie słowa „wersja” wydaje się opisywać „typ” UUID - wersja 5 nie zastępuje wersji 4).
Wydaje się, że istnieje kilka bibliotek do generowania UUID wersji 3/5, w tym moduł uuid języka Python , boost.uuid (C ++) i UUID OSSP . (Nie szukałem żadnych .net)
źródło
Musisz dokonać rozróżnienia między instancjami klasy
Guid
a identyfikatorami, które są globalnie unikalne. „Deterministyczny przewodnik” jest w rzeczywistości hashem (czego dowodem jest twoje wywołanieprovider.ComputeHash
). Hashe mają znacznie większą szansę na kolizje (dwa różne ciągi tworzą ten sam hash) niż Guid utworzony za pomocąGuid.NewGuid
.Więc problem z twoim podejściem polega na tym, że będziesz musiał zaakceptować możliwość, że dwie różne ścieżki utworzą ten sam identyfikator GUID. Jeśli potrzebujesz identyfikatora, który jest unikalny dla dowolnego ciągu ścieżki, najłatwiej jest po prostu użyć tego ciągu . Jeśli chcesz, aby ciąg został ukryty przed użytkownikami, zaszyfruj go - możesz użyć ROT13 lub czegoś mocniejszego ...
Próba włożenia czegoś, co nie jest czystym identyfikatorem GUID do typu danych GUID, może w przyszłości doprowadzić do problemów z konserwacją ...
źródło
MD5 jest słaba, wierzę, że możesz zrobić to samo z SHA-1 i uzyskać lepsze wyniki.
BTW, to tylko osobista opinia, ubranie skrótu md5 jako identyfikatora GUID nie czyni go dobrym identyfikatorem GUID. Identyfikatory GUID ze swej natury nie są deterministyczne. to wygląda na oszustwo. Dlaczego po prostu nie nazwać pik po imieniu i po prostu powiedzieć, że jest to ciąg renderowany hash wejścia. możesz to zrobić, używając tej linii zamiast nowej linii guid:
źródło
Guid
obiektu?