Una función hash convierte una clave de longitud variable en un entero reducido que actúa como índice dentro de una tabla. Su calidad determina la velocidad y estabilidad de estructuras como diccionarios o sets. En esta sección repasamos sus propiedades y mostramos implementaciones sencillas en Python.
Es una función determinista que toma una clave (entero, cadena o estructura) y devuelve un valor numérico de rango acotado. Ese valor se usa para ubicar el elemento en una tabla hash.
Se busca que todas las posiciones de la tabla reciban cantidades similares de claves. Si algunas posiciones concentran demasiados elementos, las colisiones aumentan y el tiempo promedio deja de ser O(1). Evaluar la uniformidad implica medir el factor de carga y el número de elementos por bucket.
Para que la tabla hash funcione, la función debe producir siempre el mismo valor para la misma clave en todas las ejecuciones. Esto permite guardar, buscar y eliminar de forma coherente y reproducible. Variar la semilla o la fórmula solo se hace de manera controlada (por ejemplo al rehashing).
Para enteros suele bastar con una mezcla multiplicativa que preserve bits significativos y reduzca patrones. Ejemplo:
TAM_TABLA = 1024
def hash_entero(clave):
constante = 2654435761 # fracción dorada en 32 bits
mezcla = clave * constante
return mezcla % TAM_TABLA
La multiplicación por la constante (derivada de la fracción dorada, 232/φ ≈ 2654435761) distribuye los valores de manera casi uniforme antes del módulo.
Las cadenas requieren recorrer cada carácter y mezclarlo con el acumulador. Una variante ligera es FNV-1a, que combina XOR y multiplicación:
OFFSET_BASIS = 2166136261
FNV_PRIME = 16777619
def hash_cadena_fnv(clave, tam_tabla):
hash_valor = OFFSET_BASIS
for caracter in clave:
hash_valor ^= ord(caracter)
hash_valor *= FNV_PRIME
return hash_valor % tam_tabla
FNV-1a es rápido, determinista y mezcla bien caracteres secuenciales, lo que reduce agrupamientos al usar tablas moderadas.
Elegir o ajustar la función hash es un paso central para mantener el rendimiento de la tabla sin aumentar su tamaño de forma innecesaria.