El artículo de Wikipedia sobre funciones hash es muy bueno, pero aquí daré mi opinión.
¿Qué es un hash?
"Hash" es realmente un término amplio con diferentes significados formales en diferentes contextos. No hay una sola respuesta perfecta a su pregunta. Explicaré el concepto subyacente general y mencionaré algunos de los usos más comunes del término.
Un "hash" es una función denominada función hashh
que toma como objetos de entrada y da salida a una cadena o un número. Los objetos de entrada suelen ser miembros de tipos de datos básicos como cadenas, enteros o más grandes compuestos de otros objetos como estructuras definidas por el usuario. La salida es típicamente un número o una cadena. El sustantivo "hash" a menudo se refiere a esta salida. El verbo "hash" a menudo significa "aplicar una función hash". Las principales propiedades que debe tener una función hash son:
- Debería ser fácil de calcular y
- Los resultados deben ser relativamente pequeños.
Ejemplo:
Digamos que queremos numerar hash en el rango de 0 a 999,999,999 para numerar entre 0 y 99. Una función hash simple puede ser h ( x ) = xmod100 .
Propiedades adicionales comunes:
Dependiendo del caso de uso, podríamos querer que la función hash satisfaga propiedades adicionales. Aquí hay algunas propiedades adicionales comunes:
Uniformidad : a menudo queremos que los hashes de los objetos sean distintos. Además, podemos querer que los hashes se "extiendan". Si quiero dividir algunos objetos en 100 cubos (por lo que la salida de mi función hash es un número de 0 a 99), entonces generalmente espero que aproximadamente 1/100 de los objetos caigan en el cubo 0, aproximadamente 1/100 en cubo 1, y así sucesivamente.
Resistencia de colisión criptográfica : a veces esto se lleva aún más lejos, por ejemplo, en criptografía, es posible que desee una función hash de tal manera que sea computacionalmente difícil para un adversario encontrar dos entradas diferentes que se asignen a la misma salida.
Compresión : a menudo quiero dividir entradas arbitrariamente grandes en una salida de tamaño constante o un número fijo de cubos.
Determinismo : es posible que desee una función hash cuya salida no cambie entre ejecuciones, es decir, la salida de la función hash en el mismo objeto siempre será la misma. Puede parecer que esto entra en conflicto con la uniformidad anterior, pero una solución es elegir la función hash aleatoriamente una vez, y no cambiarla entre ejecuciones.
Algunas aplicaciones
Una aplicación común está en las estructuras de datos, como una tabla hash, que son una forma de implementar diccionarios. Aquí, asigna algo de memoria, por ejemplo, 100 "cubos"; luego, cuando se le pide que almacene un par (clave, valor) en el diccionario, inserta la clave en un número 0-99 y almacena el par en el depósito correspondiente en la memoria. Luego, cuando se le pide que busque una clave, la convierte en un número 0-99 con la misma función de hash y comprueba ese depósito para ver si esa clave está allí. Si es así, devuelve su valor.
Tenga en cuenta que también podría implementar diccionarios de otras maneras, como con un árbol de búsqueda binario (si sus objetos son comparables).
Otra aplicación práctica son las sumas de verificación, que son formas de verificar que dos archivos son iguales (por ejemplo, el archivo no estaba dañado desde su versión anterior). Debido a que es poco probable que las funciones hash asignen dos entradas a la misma salida, usted calcula y almacena un hash del primer archivo, generalmente representado como una cadena. Este hash es muy pequeño, quizás solo unas pocas docenas de caracteres ASCII. Luego, cuando obtienes el segundo archivo, lo hash y compruebas que la salida es la misma. Si es así, casi con certeza es exactamente el mismo archivo byte por byte.
Otra aplicación está en la criptografía, donde estos hashes deberían ser difíciles de "invertir", es decir, dada la salida y la función hash, debería ser computacionalmente difícil averiguar las entradas que condujeron a esa salida. Un uso de esto es para las contraseñas: en lugar de almacenar la contraseña en sí, almacena un hash criptográfico de la contraseña (tal vez con algunos otros ingredientes). Luego, cuando un usuario ingresa una contraseña, usted calcula su hash y verifica que coincida con el hash correcto; Si es así, usted dice que la contraseña es correcta. (Ahora, incluso alguien que puede mirar y descubrir el hash guardado en el servidor no tiene tan fácil fingir ser el usuario). Esta aplicación puede ser un caso en el que la salida es tan larga o más larga que la entrada, ya que La entrada es muy corta.