Algoritmos Interesantes: Como obtener un Hash Numerico de un Guid.
En muchas ocasiones me ha interesado disponer de un Algoritmo que me permitiese obtener un Hash Numerico a partir de un Guid (por ejemplo para emular un Token de usuario a partir de un SID, disponer de un identificador único en memoria, etc). Recientemente, mientras trabajaba con Marcel Salla Mateus, una de las personas con las que mejor se puede trabajar por las ideas y soluciones que aporta, nos surjió la necesidad y dandole vueltas llegamos a un algoritmo que parece válido y que a nosotros nos permitió solventar un escenario bastante curioso: Crear WebSites en IIS usando WMI, y que dichos sites tuviesen el mismo identificador entre distintas máquinas de una granja, generando dicho identificador de forma aleatoria.
Al final, despues de mucho tiempo para darle vueltas y pruebas, obtuvimos un algoritmo que paso la prueba de los 10.000.000 de GUIDs distintos para obtener el mismo número de Hash numericos tipo long con 0 colisiones, y aqui lo compartimos por si resulta interesante para alguien (y también para quien quiera seguir probando su validez):
byte[] GuidArray = Guid.NewGuid().ToByteArray();
long hash1 = 0;
long hash2 = 0;
int lArrayLength = GuidArray.Length;
int lHalfArrayLength = GuidArray.Length / 2;
for (int iByte = 0; iByte < lArrayLength; iByte++)
{
if (iByte < (lHalfArrayLength))
{
hash1 |= (Convert.ToInt64(GuidArray[iByte]) << (iByte * 8));
}
else
{
hash2 += (Convert.ToInt64(GuidArray[iByte]) << ((iByte - lHalfArrayLength) * 8));
}
}
long hash = hash1 ^ hash2;//