Estoy trabajando en un sistema donde las colisiones hash serían un problema. Básicamente, hay un sistema que hace referencia a los elementos en una estructura hash-table + tree. Sin embargo, el sistema en cuestión primero compila los archivos de texto que contienen rutas en la estructura en un archivo binario que contiene los valores hash en su lugar. Esto se hace por motivos de rendimiento. Sin embargo, debido a esto, las colisiones son muy malas ya que la estructura no puede almacenar 2 elementos con el mismo valor hash; la parte que solicita un artículo no tendría suficiente información para saber cuál necesita.¿Hay una diferencia de velocidad de colisión entre un hash de 32 bits frente a dos hash de 16 bits?
Mi idea inicial es que 2 hashes, ya sea usando 2 algoritmos diferentes, o el mismo algoritmo dos veces, con 2 sales serían más resistentes a las colisiones. Dos ítems que tengan el mismo hash para diferentes algoritmos hash serían muy poco probables.
Esperaba mantener el valor hash de 32 bits por razones de espacio, así que pensé que podría cambiar a usar dos algoritmos de 16 bits en lugar de un algoritmo de 32 bits. Pero eso no aumentaría el rango de posibles valores hash ...
Sé que cambiar a dos hashes de 32 bits sería más resistente a las colisiones, pero me pregunto si al cambiar a 2 hashes de 16 bits tiene al menos algunos ganar más de un solo hash de 32 bits? No soy la persona más inclinación matemática, así que no sé ni cómo empezar la comprobación de una respuesta que no sea a la fuerza soplo que ...
Algunos antecedentes sobre el sistema:
nombresLos productos que se dan por humanos, no son cadenas aleatorias, y típicamente estarán hechas de palabras, letras y números sin espacio en blanco. Es una estructura hash anidada, así que si tuvieras algo como {a => {b => {c => 'blah'}}} obtendrías el valor 'blah' obteniendo el valor de a/b/c, solicitud compilada sería 3 valores hash en secuencia inmediata, los valores hashe de a, b, y luego c.
Solo hay un problema cuando hay una colisión en un nivel determinado. Una colisión entre un elemento en el nivel superior y un nivel inferior está bien. Puedes tener {a => {a => {...}}}, casi garantizando colisiones que están en diferentes niveles (no es un problema).
En la práctica, cualquier nivel dado probablemente tendrá menos de 100 valores para el hash, y ninguno será duplicado en el mismo nivel.
Para probar el algoritmo de hash que adopté (olvidé cuál, pero no lo inventé) descargué toda la lista de módulos de CPAN Perl, dividí todos los espacios de nombres/módulos en palabras únicas y finalmente crucifiqué cada uno buscando colisiones , Encontré 0 colisiones. Eso significa que el algoritmo tiene un valor de hash diferente para cada palabra única en la lista de espacio de nombres de CPAN (o que lo hice mal). A mí me parece lo suficientemente bueno, pero todavía molesta mi cerebro.
Estaría un poco preocupado por usar el mismo algoritmo hash de 16 bits con 2 valores de sal diferentes; los dos valores hash se correlacionan implícitamente. –
@IraBaxter Dije sal, pero creo que estaba equivocado. Me refería a usar el mismo algoritmo, pero la segunda vez prefijo un valor. El algoritmo sorbe la cadena e itera cada carácter cambiando el tiene cada vez de manera que "ab" y "ba" tendrán diferentes valores. Y dado que no tengo que preocuparme por las colisiones en cadenas idénticas (el punto de un hash) prefijar un valor a la segunda ejecución debería ser suficiente para que 2 elementos con el mismo hash después de la primera ejecución tengan un hash diferente en el segundo . (De nuevo, me gustaría confirmar que) – Exodist
@ ira-baxter: Si el algoritmo hash es criptográficamente seguro, no debería haber tal correlación. Sin embargo, eso es un si eso no debe ser ignorado. – btilly