¿Cómo puedo generar un GUID para una cadena?

Tengo un problema para generar un GUID para una cadena, por ejemplo:

Guid g = New Guid("Mehar"); 

¿Cómo puedo calcular un GUID para "Mehar" ? Estoy recibiendo una excepción.

Bastante viejo este hilo pero así es como resolvimos este problema:

Como los Guid del marco .NET son 16bytes arbitrarios, o respectivamente 128bits, puede calcular un Guid a partir de cadenas arbitrarias aplicando cualquier función de hash a la cadena que genera un hash de 16 bytes y posteriormente pasar el resultado al constructor de Guid.

Decidimos usar la función hash MD5 y un código de ejemplo podría verse así:

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

Tenga en cuenta que esta generación de Guid tiene algunas fallas por sí misma, ya que depende de la calidad de la función hash. Si su función hash genera hashes iguales para una gran cantidad de cadenas que utiliza, afectará el comportamiento de su software.

Aquí hay una lista de las funciones hash más populares que producen un resumen de 128 bits:

  • RIPEMD (probabilidad de colisión: 2 ^ 18)
  • MD4 (probabilidad de colisión: seguro)
  • MD5 (probabilidad de colisión: 2 ^ 20.96)

Tenga en cuenta que también se pueden usar otras funciones hash que producen resúmenes más grandes y simplemente truncarlos. Por lo tanto, puede ser inteligente usar una función hash más nueva. Para enumerar algunos:

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

Hoy (agosto de 2013) el hash SHA1 de 160 bits se puede considerar como una buena opción.

Estoy bastante seguro de que has confundido a System.Guid con querer un hash (por ejemplo, SHA-256 ) de una cadena dada.

Tenga en cuenta que, al seleccionar un algoritmo de hash criptográficamente seguro, MD5, SHA0 y SHA1 generalmente se consideran muertos . SHA2 y más aún son utilizables.

Lo que está buscando es probablemente generar UUIDs de la versión 3 o 5, que son UUID basados ​​en nombres. (La versión 5 es la recomendada). No creo que el .NET Framework tenga soporte incorporado para él. Ver http://en.wikipedia.org/wiki/Universally_Unique_Identifier

Hice algunas búsquedas en Google para ver si podía encontrar algo en la API de Win32, pero no surgió nada. Sin embargo, estoy seguro de que .NET Framework tiene alguna implementación oculta en algún lugar, porque, por lo que sé, al generar un objeto COM en .NET, y no proporciona un GUID explícito, entonces .NET Framework genera un nombre. UUID basado para crear un ClassID e InterfaceID bien definidos, es decir, UUID que no cambian cada vez que se recomstack (como VB6). Pero esto probablemente esté oculto, así que supongo que necesitas implementar el algoritmo por ti mismo. Afortunadamente, .NET proporciona un algoritmo MD5 y SHA1, por lo que no creo que la implementación de un UUID versión 3 y versión 5 sea demasiado difícil.

No puedes usar GUID de esa manera. El constructor de Guid espera una representación de cadena válida de un Guid.

Lo que buscas se llama función hash. (por ejemplo: MD5 )

Creo que tienes un malentendido de lo que realmente es un Guid. No hay una representación Guid de una cadena como “Mehar”.

La razón por la que hay una new Guid(String s) sobrecarga new Guid(String s) es para que pueda crear un guid a partir de una representación típica de una cadena, como “00000000-0000-0000-0000-000000000000”.

Consulte el artículo de la wiki para obtener más información sobre lo que realmente es un Guid.

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

En general, hay algunas formas de hacer una ID única universal (UUID RFC 4122 , también conocido como GUID). Podríamos tomar prestados estos cuatro de Python, y hacer en C # algo parecido:

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

Genere un UUID a partir de una ID de host, número de secuencia y la hora actual. Si no se proporciona el nodo, se usa getnode () para obtener la dirección del hardware. Si se da clock_seq, se usa como el número de secuencia; De lo contrario, se elige un número de secuencia de 14 bits aleatorio.

uuid.uuid3(namespace, name)

Genere un UUID basado en el hash MD5 de un identificador de espacio de nombres (que es un UUID) y un nombre (que es una cadena).

uuid.uuid4()

Generar un UUID aleatorio.

uuid.uuid5(namespace, name)

Genere un UUID basado en el hash SHA-1 de un identificador de espacio de nombres (que es un UUID) y un nombre (que es una cadena).

Entonces, si necesita el ID de una cadena como un objeto, no el ID de un valor, debe modificar su UUID privado con la cadena dada. Su UUID privado se genera una vez usando uuid1 , y luego lo usa como espacio de nombres para uuid3 o uuid5 .

Estas variantes y versiones se describen en Wikipedia Universally_unique_identifier # Variants_and_versions

Si la intención de op es crear un UUID (Guid) a partir de un hash de algún tipo (MD5, SHA-1, etc.), encontré esta pregunta muy similar con esta gran respuesta:

https://stackoverflow.com/a/5657517/430885

Tiene un enlace a un github-snippet basado en RFC 4122 §4.3, que creará un Guid a partir de una cadena y un espacio de nombres (que puede elegir para garantizar las colisiones desde entornos externos).

Enlace directo al fragmento: https://github.com/LogosBible/Logos.Utility/blob/master/src/Logos.Utility/GuidUtility.cs

Este es mi propio enfoque, intencionalmente estoy usando String para hacer volcado hexadecimal si es posible, visualmente se puede ver al menos qué cadena es grande, y si es necesario, se descodifica usando algún convertidor hexadecimal en línea. Pero si la cadena es demasiado larga (más de 16 bytes), usar sha-1 para calcular el hash y generar guid a partir de ella.

 ///  /// Generates Guid based on String. Key assumption for this algorithm is that name is unique (across where it it's 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. ///  /// Unique name which is unique across where this guid will be used. /// For example "{706C7567-696E-7300-0000-000000000000}" for "plugins" 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; } 

Las guías son aleatorias, no se asignan intrínsecamente a ninguna cadena u otro valor.

Si necesita dicha vinculación, almacene las guías en un Diccionario y busque una guía existente antes de crear una nueva.

Utiliza el método estático NewGuid () para crear Guids, IE, Guid g = Guid.NewGuid(); o string s = Guid.NewGuid().ToString()'