Nunca es tarde para un buen tema y estoy seguro que la gente estaría interesada en mis conclusiones.
que necesitaba una función hash y después de leer este post y hacer un poco de investigación sobre los vínculos que se dan aquí, me ocurrió con esta variación del algoritmo de Daniel J. Bernstein, que yo solía hacer una prueba interesante:
unsigned long djb_hashl(const char *clave)
{
unsigned long c,i,h;
for(i=h=0;clave[i];i++)
{
c = toupper(clave[i]);
h = ((h << 5) + h)^c;
}
return h;
}
Esta variante hashes de cadenas ignorando el caso, que se adapta a mi necesidad de hashing credenciales de inicio de sesión de los usuarios. 'clave' es 'clave' en español. Lo siento por el español, pero es mi lengua materna y el programa está escrito en él.
Bueno, escribí un programa que generará nombres de usuario de 'test_aaaa' a 'test_zzzz', y -para alargar las cadenas- les agregué un dominio aleatorio en esta lista: 'cloud-nueve.com', 'yahoo.com', 'gmail.com' y 'hotmail.com'. Por lo tanto cada uno de ellos sería el resultado:
[email protected], [email protected],
[email protected], [email protected] and so on.
Aquí está la salida de la prueba -'Colision Entre XXX y XXX' significa 'colisión de XXX y XXX'. 'palabras' significa 'palabras' y 'Total' es el mismo en ambos idiomas-.
Buscando Colisiones...
Colision entre '[email protected]' y '[email protected]' (1DB903B7)
Colision entre '[email protected]' y '[email protected]' (2F5BC088)
Colision entre '[email protected]' y '[email protected]' (51FD09CC)
Colision entre '[email protected]' y '[email protected]' (52F5480E)
Colision entre '[email protected]' y '[email protected]' (74FF72E2)
Colision entre '[email protected]' y '[email protected]' (7FD70008)
Colision entre '[email protected]' y '[email protected]' (9BD351C4)
Colision entre '[email protected]' y '[email protected]' (A86953E1)
Colision entre '[email protected]' y '[email protected]' (BA6B0718)
Colision entre '[email protected]' y '[email protected]' (D0523F88)
Colision entre '[email protected]' y '[email protected]' (DEE08108)
Total de Colisiones: 11
Total de Palabras : 456976
Eso no es malo, 11 colisiones de cada 456.976 (por supuesto usando el pleno de 32 bits como longitud de la tabla).
Ejecutando el programa usando 5 caracteres, que es de 'test_aaaaa' a 'test_zzzzz', se está quedando sin memoria creando la tabla. Debajo está la salida.'No hay memoria para insertar XXXX (insertadas XXX)' significa 'No queda memoria para insertar XXX (XXX insertado)'. Básicamente malloc() falló en ese punto.
No hay memoria para insertar 'test_epjcv' (insertadas 2097701).
Buscando Colisiones...
...451 'colision' strings...
Total de Colisiones: 451
Total de Palabras : 2097701
Lo que significa solo 451 colisiones en 2,097,701 cadenas. Tenga en cuenta que en ninguna de las ocasiones, hubo más de 2 colisiones por código. Lo cual confirmo que es un gran hash para mí, ya que lo que necesito es convertir el ID de inicio de sesión en una identificación única de 40 bits para indexar. Así que utilizo esto para convertir las credenciales de inicio de sesión a un hash de 32 bits y uso los 8 bits adicionales para manejar hasta 255 colisiones por código, lo que indica que los resultados de la prueba serían casi imposibles de generar.
Espero que esto sea útil para alguien.
EDIT:
Al igual que la caja de prueba es AIX, lo corro usando LDR_CNTRL = MAXDATA = 0x20000000 para darle más memoria y más largo plazo, los resultados están aquí:
Buscando Colisiones. .. Total de Colisiones: 2908 Total de Palabras: 5366384
Eso es 2908 después de 5,366,384 intentos !!
MUY IMPORTANTE: La compilación del programa con -maix64 (por lo que unsigned long es de 64 bits), el número de colisiones es 0 para todos los casos !!!
por favor agregue palabras clave: algoritmo hash unique colisión baja – slashmais
La siguiente página tiene varias implementaciones de funciones hash de propósito general que son "performant" y tienen bajas "tasas de colisión": http://partow.net/programming/hashfunctions/index.html –