En nuestra aplicación estamos creando archivos Xml con un atributo que tiene un valor Guid. Este valor debía ser coherente entre las actualizaciones de archivos. Entonces, incluso si todo lo demás en el archivo cambia, el valor de guid para el atributo debería permanecer igual.
Una solución obvia fue crear un diccionario estático con el nombre del archivo y las guías que se utilizarían para ellos. Luego, cada vez que generamos el archivo, buscamos en el diccionario el nombre del archivo y usamos el guid correspondiente. Pero esto no es factible porque podríamos escalar a cientos de archivos y no queríamos mantener una gran lista de guías.
Entonces, otro enfoque fue hacer que el Guid fuera el mismo en función de la ruta del archivo. Dado que nuestras rutas de archivo y la estructura del directorio de la aplicación son únicas, el Guid debe ser único para esa ruta. Entonces, cada vez que ejecutamos una actualización, el archivo obtiene la misma guía en función de su ruta. Encontré una manera genial de generar tales ' Guías deterministas ' (Gracias Elton Stoneman). Básicamente hace esto:
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;
}
Entonces, dada una cadena, el Guid siempre será el mismo.
¿Existen otros enfoques o formas recomendadas para hacer esto? ¿Cuáles son los pros o los contras de ese método?
Esto convertirá cualquier cadena en un Guid sin tener que importar un ensamblaje externo.
Hay formas mucho mejores de generar un Guid único, pero esta es una forma de actualizar constantemente una clave de datos de cadena a una clave de datos de Guid.
fuente
Como menciona Rob, su método no genera un UUID, genera un hash que parece un UUID.
El RFC 4122 en UUID permite específicamente UUID deterministas (basados en nombres): las versiones 3 y 5 usan md5 y SHA1 (respectivamente). La mayoría de las personas probablemente estén familiarizadas con la versión 4, que es aleatoria. Wikipedia ofrece una buena descripción general de las versiones. (Tenga en cuenta que el uso de la palabra 'versión' aquí parece describir un 'tipo' de UUID; la versión 5 no reemplaza a la versión 4).
Parece que existen algunas bibliotecas para generar UUID de la versión 3/5, incluido el módulo uuid de python , boost.uuid (C ++) y UUID OSSP . (No he buscado ninguno .net)
fuente
Debe hacer una distinción entre las instancias de la clase
Guid
y los identificadores que son únicos globalmente. Una "guía determinista" es en realidad un hash (como lo demuestra su llamada aprovider.ComputeHash
). Los hash tienen una probabilidad mucho mayor de colisiones (dos cadenas diferentes producen el mismo hash) que Guid creado a través deGuid.NewGuid
.Entonces, el problema con su enfoque es que tendrá que estar de acuerdo con la posibilidad de que dos rutas diferentes produzcan el mismo GUID. Si necesita un identificador que sea único para cualquier cadena de ruta determinada, entonces lo más fácil de hacer es usar la cadena . Si necesita que sus usuarios no vean la cadena, encriptarla ; puede usar ROT13 o algo más poderoso ...
Intentar calzar algo que no sea un GUID puro en el tipo de datos GUID podría generar problemas de mantenimiento en el futuro ...
fuente
MD5 es débil, creo que puede hacer lo mismo con SHA-1 y obtener mejores resultados.
Por cierto, solo una opinión personal, disfrazar un hash md5 como un GUID no lo convierte en un buen GUID. Los GUID por su propia naturaleza no son deterministas. esto se siente como una trampa. ¿Por qué no llamar a una espada espada y decir que es una cadena representada como hash de la entrada? podría hacerlo usando esta línea, en lugar de la nueva línea de guía:
fuente
Guid
objeto?