¿Qué significa hashing?

Hashing: la idea es usar la función hash que convierte un número de teléfono dado o cualquier otra tecla a un número más pequeño y usa el número pequeño como índice en una tabla llamada tabla hash.

Función hash: una función hash asigna un gran número o cadena a un entero pequeño que se puede usar como índice en la tabla hash. Una buena función Hash debería ser eficientemente computable y debería distribuir uniformemente las claves.

Manejo de colisiones: dado que una función hash nos da un número pequeño para una clave grande, existe la posibilidad de que dos claves den como resultado el mismo valor. La situación en la que una clave recién insertada se asigna a una ranura ya ocupada en la tabla hash se llama colisión y debe manejarse utilizando alguna técnica de manejo de colisión.

Las siguientes son las formas de manejar las colisiones:

  1. Encadenamiento: la idea es hacer que cada celda de la tabla hash apunte a una lista vinculada de registros que tengan el mismo valor de función hash. El encadenamiento es simple, pero requiere memoria adicional fuera de la tabla.
  2. Direccionamiento abierto: en el direccionamiento abierto, todos los elementos se almacenan en la propia tabla hash. Entonces, en cualquier punto, el tamaño de la tabla debe ser mayor o igual que el número total de claves. Logrado por el sondeo lineal, el sondeo cuadrático o el hash.

Encadenamiento separado: fácil de implementar y la tabla hash nunca se llena. Se usa principalmente cuando se desconoce cuántas y con qué frecuencia se pueden insertar o eliminar claves.

    1. Evaluación del rendimiento del encadenamiento: el rendimiento del hashing se puede evaluar bajo el supuesto de que cada clave tiene la misma probabilidad de ser hash en cualquier ranura de la tabla (hashing uniforme).
    2. m = Número de ranuras en la tabla hash
      n = El número de claves a insertar en la tabla tiene
      Factor de carga α = n / m
      Tiempo esperado de búsqueda = O (1 + α)
      Tiempo esperado para insertar / eliminar = O (1 + α)
    3. La complejidad temporal de la inserción y eliminación de búsqueda es O (1) si α es O (1)
    4. Desventaja: el rendimiento del encadenamiento de la memoria caché no es bueno, ya que las claves se almacenan mediante una lista vinculada. El desperdicio de espacio como enlaces se utilizan y algunas partes hash nunca se utilizan. Si la cadena se alarga, el tiempo de búsqueda puede convertirse en O (n) en el peor de los casos.

Direccionamiento abierto :

Insertar (k): siga sondeando hasta encontrar una ranura vacía. Una vez que se encuentre una ranura vacía, inserte k.

Búsqueda (k): siga sondeando hasta que la clave del espacio no sea igual a k o se alcance un espacio vacío.

Eliminar (k): la operación de eliminación es interesante. Si simplemente eliminamos una clave, entonces la búsqueda puede fallar. Por lo tanto, las ranuras de las teclas eliminadas se marcan especialmente como “eliminadas”. Insertar puede insertar un elemento en una ranura eliminada, pero la búsqueda no se detiene en una ranura eliminada.

  1. Sondeo lineal : en el sondeo lineal, realizamos sondeos lineales para la siguiente ranura. Deje que hash (x) sea el índice de ranura calculado utilizando la función hash y S sea el tamaño de la tabla.

Si el hash de ranura (x)% S está lleno, entonces intentamos (hash (x) + 1)% S
Si (hash (x) + 1)% S también está lleno, entonces intentamos (hash (x) + 2)% S
Si (hash (x) + 2)% S también está lleno, entonces intentamos (hash (x) + 3)% S
………………………………………… ..

2. Agrupación: el principal problema con el sondeo lineal es la agrupación, muchos elementos consecutivos forman grupos y comienza a tomar tiempo para encontrar un espacio libre o buscar un elemento.

3. Sondeo cuadrático: buscamos la ranura número 2 en la iteración. El hash (x) sea el índice de ranura calculado utilizando la función hash.

Si el hash de ranura (x)% S está lleno, entonces intentamos (hash (x) + 1 * 1)% S
Si (hash (x) + 1 * 1)% S también está lleno, entonces intentamos (hash (x) + 2 * 2)% S
Si (hash (x) + 2 * 2)% S también está lleno, entonces intentamos (hash (x) + 3 * 3)% S
………………………………………… ..

4. Doble Hash : utilizamos otra función de hash hash2 (x) y buscamos la ranura i * hash2 (x) en la i-ésima rotación.

deje que hash (x) sea el índice de ranura calculado usando la función hash.
Si el hash de ranura (x)% S está lleno, entonces intentamos (hash (x) + 1 * hash2 (x))% S
Si (hash (x) + 1 * hash2 (x))% S también está lleno, entonces intentamos (hash (x) + 2 * hash2 (x))% S
Si (hash (x) + 2 * hash2 (x))% S también está lleno, entonces intentamos (hash (x) + 3 * hash2 (x))% S
………………………………………… ..

El sondeo lineal tiene el mejor rendimiento de caché, pero sufre de agrupamiento. Una ventaja más del sondeo lineal es fácil de calcular. El sondeo cuadrático se encuentra entre los dos en términos de rendimiento de caché y agrupación. El doble hashing tiene un rendimiento de caché deficiente pero no agrupa. El doble hashing requiere más tiempo de cálculo ya que se deben calcular dos funciones hash.

Evaluación del rendimiento de direccionamiento abierto : al igual que el encadenamiento, el rendimiento del hash se puede evaluar bajo el supuesto de que cada clave tiene la misma probabilidad de ser hash en cualquier ranura de la tabla (hashing uniforme simple) m = Número de ranuras en la tabla hash
n = El número de claves a insertar en la tabla tiene
Factor de carga α = n / m (<1)
Tiempo esperado para buscar / insertar / eliminar <1 / (1 – α)
Entonces Buscar, Insertar y Eliminar toma tiempo (1 / (1 – α))
El direccionamiento abierto requiere un cuidado especial para evitar la agrupación y el factor de carga.

En su forma más simple, el hash es cuando una función que toma una entrada de tamaño variable y devuelve una variable de tamaño fijo cuyo valor siempre será el mismo dada la misma entrada.

Analicemos eso:

hashing es cuando una función

Cuando digo una función me refiero a un algoritmo. Cuando hablamos de hashing, generalmente hablamos del algoritmo de hashing que se está utilizando. Los ejemplos pueden ser CRC32, MD5, SHA256 o cualquiera de los muchos otros. Si el algoritmo se implementa en C o Java o cualquier cosa no importa. Cualquiera de las dos implementaciones del mismo algoritmo se comportará igual. Siempre.

que toma una entrada de tamaño variable

Una función hash puede (generalmente) aceptar entradas de tamaño arbitrario. Podría ser la cadena “Hello World” o un blob binario que tiene un tamaño de terabytes (¡o más!). El punto es que el tamaño de entrada no está definido por el algoritmo (o función). Simplemente opera con lo que se le dio.

y devuelve una variable de tamaño fijo

Las funciones hash devuelven un valor que es un tamaño fijo. CRC32 siempre devuelve un valor de 32 bits (independientemente de si la entrada fue mayor o menor que 32 bits). MD5 siempre devuelve un valor de 128 bits. SHA256 siempre devuelve un valor de 256 bits. Siempre.

Esto tiene una implicación muy importante.

La salida de una función hash no se puede utilizar para aplicar ingeniería inversa a la entrada. Piénsalo. Si hash un archivo de 2GB en un valor de 128 bits, no hay forma de recuperar los 2GB. Si lo hubiera, tendrías el santo grial de la compresión.

cuyo valor siempre será el mismo dada la misma entrada.

Esta es la pieza crítica de todo el asunto: si se proporciona la misma entrada a la misma función hash (algoritmo) varias veces, siempre (SIEMPRE) devolverá la misma salida.

Misma entrada = misma salida. Cada vez. Sin excepciones.

¡Probemos esto!

Busqué en Google “calculadora MD5” y fui a los primeros tres sitios web que ofrecían hashing MD5 en línea desde entradas arbitrarias:

Generador de hash MD5

Generador de hash MD5 en línea y generador de hash SHA1

CALCULADORA DE HASH EN LÍNEA MD5

Fui a cada sitio e ingresé el siguiente valor:

Hola Mundo

No utilicé comillas y no había espacio final. La entrada distingue entre mayúsculas y minúsculas.

Cada sitio devolvió el mismo valor (el hash resultante no distingue entre mayúsculas y minúsculas):

b10a8db164e0754105b7a99be72e3fe5

Ese valor es el valor de 128 bits representado como 22 caracteres en la codificación base 64.

Por lo tanto, cada sitio implementa el mismo algoritmo que tomó una entrada de tamaño variable y devolvió un resultado de tamaño fijo cuyo valor era el mismo dada la misma entrada.

Eso es lo que significa hashing.

More Interesting

¿Cuál es la diferencia entre la estructura de datos y la base de datos para almacenar datos?

Se le da una matriz de números MxN, con la propiedad de que los números aumentan a medida que avanza por cada columna y hacia la derecha en cada fila. ¿Cómo puede verificar eficientemente si un número dado está en la matriz?

¿Qué problemas comunes se resuelven con la programación dinámica?

¿Cuáles son los mejores algoritmos de agrupamiento para puntos de datos numéricos multidimensionales?

Si estudié modelado matemático financiero avanzado en la universidad con un coeficiente intelectual de 145, ¿con qué probabilidad podría construir un algoritmo HFT rentable?

¿Cuáles son algunos avances en ciencias de la computación realizados por científicos mientras trabajaban en la industria?

¿Qué es un filtro adaptativo?

En los lenguajes de programación donde una matriz crece dinámicamente en tamaño, ¿no es una preocupación porque es O (n) complejidad de tiempo?

¿Existe un algoritmo para aplicar a una imagen que muestre lo que vería alguien que necesita corrección de la visión?

¿Cuál es la relación entre matrices y matrices variables de programas de computadora?

¿Qué algoritmo en aprendizaje automático es el más adecuado para unir los datos entrantes nuevos con los datos existentes en la base de datos SQLite?

¿Qué alternativas hay para los algoritmos de escalada?

¿Podemos hacerlo mejor en complejidad de tiempo que el siguiente código para calcular la suma de los primeros 10 primos?

¿Cuál es el propósito de construir un árbol de expansión mínimo?

¿Cuál es el orden cronológico de los algoritmos de reconocimiento facial?