Dans notre application, nous créons des fichiers Xml avec un attribut qui a une valeur Guid. Cette valeur devait être cohérente entre les mises à niveau de fichiers. Ainsi, même si tout le reste du fichier change, la valeur guid de l'attribut doit rester la même.
Une solution évidente était de créer un dictionnaire statique avec le nom de fichier et les Guids à utiliser pour eux. Ensuite, chaque fois que nous générons le fichier, nous recherchons dans le dictionnaire le nom de fichier et utilisons le guid correspondant. Mais ce n'est pas faisable car nous pourrions passer à des centaines de fichiers et ne voulions pas maintenir une grande liste de guides.
Une autre approche consistait donc à rendre le Guid identique en fonction du chemin du fichier. Étant donné que nos chemins de fichiers et notre structure de répertoires d'application sont uniques, le Guid doit être unique pour ce chemin. Ainsi, chaque fois que nous exécutons une mise à niveau, le fichier obtient le même GUID en fonction de son chemin. J'ai trouvé un moyen sympa de générer de tels « guides déterministes » (merci Elton Stoneman). Il fait essentiellement ceci:
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;
}
Donc, étant donné une chaîne, le Guid sera toujours le même.
Y a-t-il d'autres approches ou moyens recommandés pour y parvenir? Quels sont les avantages ou les inconvénients de cette méthode?
Cela convertira n'importe quelle chaîne en Guid sans avoir à importer un assembly extérieur.
Il existe de bien meilleures façons de générer un Guid unique, mais c'est un moyen de mettre à niveau de manière cohérente une clé de données de chaîne vers une clé de données Guid.
la source
Comme Rob le mentionne, votre méthode ne génère pas d'UUID, elle génère un hachage qui ressemble à un UUID.
La RFC 4122 sur les UUID autorise spécifiquement les UUID déterministes (basés sur le nom) - Les versions 3 et 5 utilisent md5 et SHA1 (respectivement). La plupart des gens connaissent probablement la version 4, qui est aléatoire. Wikipedia donne un bon aperçu des versions. (Notez que l'utilisation du mot «version» ici semble décrire un «type» d'UUID - la version 5 ne remplace pas la version 4).
Il semble y avoir quelques bibliothèques là-bas pour générer des UUID version 3/5, y compris le module uuid python , boost.uuid (C ++) et OSSP UUID . (Je n'ai pas cherché de .net)
la source
Vous devez faire une distinction entre les instances de la classe
Guid
et les identificateurs qui sont globalement uniques. Un "guid déterministe" est en fait un hachage (comme en témoigne votre appel àprovider.ComputeHash
). Les hachages ont un risque beaucoup plus élevé de collisions (deux chaînes différentes produisant le même hachage) que Guid créé viaGuid.NewGuid
.Le problème avec votre approche est que vous devrez accepter la possibilité que deux chemins différents produisent le même GUID. Si vous avez besoin d'un identifiant unique pour une chaîne de chemin donnée, la chose la plus simple à faire est simplement d'utiliser la chaîne . Si vous avez besoin que la chaîne soit masquée par vos utilisateurs, cryptez-la - vous pouvez utiliser ROT13 ou quelque chose de plus puissant ...
Tenter d'afficher quelque chose qui n'est pas un GUID pur dans le type de données GUID pourrait entraîner des problèmes de maintenance à l'avenir ...
la source
MD5 est faible, je pense que vous pouvez faire la même chose avec SHA-1 et obtenir de meilleurs résultats.
BTW, juste une opinion personnelle, habiller un hachage md5 comme un GUID n'en fait pas un bon GUID. Les GUID de par leur nature même ne sont pas déterministes. cela ressemble à une triche. Pourquoi ne pas simplement appeler un chat un chat et dire simplement que c'est une chaîne rendue hachée de l'entrée. vous pouvez le faire en utilisant cette ligne, plutôt que la nouvelle ligne de guidage:
la source
Guid
objet?