Hashing Flashcards

1
Q

Defina funcion de hashing.

A

En su más básica definición una función de hashing debe ser capaz de recibir como input un cierto dato cualquiera y devolver un número acotado a un cierto intervalo. Al conjunto de claves posibles (input) lo denominaremos ”espacio de claves” y al conjunto de números que la función de hashing puede devolver lo llamaremos ”espacio de direcciones”.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Explique mecanismos de resolucion de colisiones.

A

i) Búsqueda lineal (direccionamiento abierto o hashing cerrado)
La búsqueda lineal es una solución muy sencilla al problema de las colisiones. Cuando queremos almacenar un dato pero su posición está ocupada buscamos linealmente y de forma cı́clica hasta encontrar un lugar libre o bien hasta volver al lugar original en cuyo caso la tabla está llena. Cuando queremos recuperar un dato tenemos que tener en cuenta que si en la posición indicada por la función de hashing encontramos otro dato entonces el dato que buscamos podrı́a estar en otra posición por lo que tenemos que buscar linealmente hasta encontrar el dato o bien un lugar vacı́o. Notemos que si se permiten bajas no podemos detenernos al encontrar una posición dada de baja.

La búsqueda lineal es sencilla pero a medida que aumenta la cantidad de datos en la tabla degrada muy rápidamente y se parece mucho a una simple búsqueda lineal que es O(n) en lugar de O(1).

ii) Encadenamiento de Sinónimos (direccionamiento cerrado o hashing abierto)
En este método vamos a generar una lista enlazada en cada posición de nuestra tabla de hash para almacenar allı́ las claves que colisionen. Nuestra estructura es entonces un vector de listas. Cuando queremos almacenar un dato simplemente lo agregamos a la lista que está en la posición indicada por la función de hashing. Cuando queremos buscar un dato accedemos a la lista indicada por la función de hashing y buscamos en la lista.

Este método es muy sencillo y es un poco mas eficiente que la búsqueda lineal pero cuando existen muchas colisiones las listas pueden volverse bastante largas por lo que las búsquedas pueden tender a O(n) en lugar de O(1). No obstante es un método muy usado y que debemos tener en cuenta ya que tiene varias aplicaciones interesantes.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Que se quiere garantizar con Hopscotch hashing?

A

Queremos garantizar O(1) para las búsquedas y queremos que la zona en la cual tenemos que buscar el dato sea igual o muy cercana a la indicada por la función de hashing para favorecer el uso de datos en memoria cache.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Explique hopscotch hashing.

A

En Hopscotch partimos de un vector de ”m” elementos que es nuestra tabla de hash, vamos a usar además un número ”k” que indica que tan lejos podemos guardar un dato respecto de la posición indicada por la función de hashing. Si k=3 podemos guardar el dato en h(x), h(x)+1 o h(x)+2. Es decir que cada dato tiene k posiciones en las cuales puede almacenarse. Es importante mencionar que esto no quiere decir que si esas k posiciones están ocupadas el dato no pueda almacenarse.

La forma de resolver colisiones en Hopscotch es muy interesante y muy simple. En primer lugar consideremos las posiciones h(x), h(x)+1 hasta h(x)+k-1, si alguna de esas posiciones está libre entonces podemos guardar el dato allı́ sin ningún problema. Si todas las posiciones están ocupadas entonces buscamos linealmente hasta encontrar una posición libre y a partir de esta recorremos hacia atrás viendo si podemos ir moviendo datos hacia adelante de forma de liberar una posición válida para nuestro dato.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Que sucede en el caso que no se pueda liberar un espacio en las k posiciones en Hopscotch hashing?

A

En el caso que no se pueda liberar un espacio en las k posiciones donde puede almacenarse el dato, se debe cambiar el tamaño de la tabla y reubicar a los datos de la misma.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Enuncie las propiedades que debe cumplir una funcion de hashing.

A
  1. La función tiene que ser muy eficiente, es decir, generar el resultado en muy poco tiempo.
    El motivo por el cual usamos una función de hashing es para poder recuperar un dato de forma muy eficiente en tiempo similar a O(1). Si la función de hashing fuera muy compleja e ineficiente podrı́a pasar que buscar linealmente en el vector tarde menos tiempo que usar la función de hashing y acceder a la posición indicada, lo cual invalidarı́a el uso de una función de hashing por completo.
  2. La función tiene que producir la menor cantidad de colisiones posibles.
    El segundo punto pide minimizar las colisiones, lo cual no solo implica evitar, en lo posible, que nuestras claves colisionen sino que debemos intentar que la distribución de las claves en el espacio de direcciones sea lo más pareja posible.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

FNV hashing.

A
Data: s: string
Result: h: integer
1 h = 14695981039346656037;
2 for c in s do
3     h = h * 1099511628211;
4     h = h XOR c;
5 return h;
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Jenkins

A
Data: s: string
Result: hash: integer
1 for hash=i=0;i> 6);
5 hash += (hash << 3);
6 hash xor= (hash >> 11);
7 hash += (hash << 15);
8 return hash;
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Pearson.

A
Data: s: string
Result: hash: integer
1 h = 0;
2 for c in s do
3     index = h xor c;
4     h = T[index];
5 return h
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

A que cosa es Pearson una primera aproximacion y por que?

A

La función de Pearson nos permite también una primera aproximación rudimentaria a una función de hashing perfecta. Si tenemos pocas claves a hashear podemos simplemente probar diferentes tablas al azar hasta que alguna de las tablas nos genere una función de Pearson que sea perfecta. Este es un algoritmo aleatorizado de tipo Las Vegas ya que siempre produce un resultado exacto pero con una cierta probabilidad, aunque puede tardar mucho tiempo en generar el resultado.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Caracteristicas de funciones de hashing criptograficas.

A
  1. La función tiene que producir la menor cantidad de colisiones posibles
  2. Dado h(x) tiene que ser muy difı́cil hallar x
  3. Tiene que ser muy difı́cil hallar x e y de forma tal que h(x)=h(y)
  4. Un cambio mı́nimo en la clave tiene que producir un cambio significativo en el resultado (efecto avalancha)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Cual es la funcion de hash cript. mas usada hoy dia y en que se basa?

A

SHA-256 se basa en la combinación de dos primitivas criptográficas muy importantes: La construcción de Merkle-Damgard y la construcción de Davis-Meyer.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Explique construccion de Merkle-Damgard.

A

En esta construcción suponemos que existe una función ”f” que recibe un bloque de m bits y devuelve un bloque de n bits con n < m. A esta función se la llama función de compresión aunque no tiene nada que ver con compresión de datos. Simplemente devuelve menos bits que los que recibe.

El objetivo de la construcción de Merkle-Damgard es dado un string de una cantidad arbitraria de bits emitir un único resultado de tamaño igual al tamaño que emite la función f.

Supongamos que ”n” es la cantidad de bits que emite nuestra función de compresión f, dividimos nuestro mensaje entonces en bloques de ”n” bits agregando un padding al final en caso de ser necesario. El padding es crı́tico para el correcto funcionamiento de la función y no debe ser fijo.

Como la función de compresión recibe bloques de m bits agregamos un bloque ficticio llamado IV con el cual podemos comenzar el algoritmo. Notar que la construcción es muy simple y se basa en concatenar el resultado anterior de f al bloque próximo y luego volver a aplicar f.

Mediante la construcción de Merkle-Damgard podemos aplicar una función de compresión cualquiera a un mensaje de longitud arbitraria de forma segura, veamos ahora como construir una función de compresión segura.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Explique construccion de Davis-Meyer.

A

La construcción de Davis-Meyer permite generar una función de compresión segura a partir de un algoritmo de encripción seguro. El procedimiento es muy simple, recibimos dos bloques y usaremos uno como clave para encriptar el otro, finalizando con el xor entre el bloque 1 y el resultado de la encripción.

SHA-256 es entonces una construcción de Merkle-Damgard en donde la función de compresión es una construcción de Davis-Meyer usando SHACAL-2 como algoritmo de encripción. Cada bloque del mensaje tiene 512 bits y la función de compresión devuelve 256 bits.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Son intercambiables las funciones de hashing tradicionales y criptograficas? Por que?

A

Es importante destacar que es un error muy grave usar una función de hashing tradicional cuando se necesita una función de hashing criptográfica pero también es un error grave usar una función criptográfica cuando solo necesitamos una función de hashing tradicional. Esto es porque las funciones criptográficas son menos eficientes y estarı́amos perdiendo velocidad a cambio de propiedades adicionales que no necesitamos!

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Explique el concepto de Hashing universal.

A

El concepto de Hashing Universal pasa por construir, no una función de hashing, sino una familia de funciones de hashing, de forma tal que podamos elegir las funciones que necesitemos entre el total de funciones que constituyen dicha familia.

17
Q

Defina hashing universal.

A

Para cualquier función de hashing de nuestra familia la probabilidad de que dos claves diferentes colisionen debe ser menor o igual a 1/m, siendo m el espacio de direcciones de cada una de las funciones de hashing de la familia.

18
Q

De la funcion de Carter-Wegman. Para que se usa?

A

h(x) = (a ∗ x + b (mod p)) (mod m)

p: un número primo mayor o igual a m
a: un número entre 1 y p − 1
b: un número entre 0 y p − 1

Se usa para valores atomicos (numericos).

19
Q

Hashing para claves de long. fija.

A

Sea m, nuestro espacio de direcciones, p un número primo mayor o igual a m y sean claves x compuestas por r + 1 números: x 0 ..x r . Vamos a elegir r + 1 números a i entre 1 y m-1 y nuestra función de hashing quedará definida por:

sum (de i=0 a r) de: (a i ∗ x i (mod p)) (mod m)

Notemos que hemos definido una familia de funciones de hashing ya que por cada selección de los parámetros a i creamos una función diferente. En concreto como cada a i puede tomar un valor entre 0 y m − 1 hay un total de m r+1 funciones de hashing en nuestra familia.

20
Q

Hashing para claves de long. variable.

A

Consideramos ahora el caso en el cual nuestras claves tienen longitud variable y no hay una longitud máxima definida. Si existiera una longitud máxima para las claves entonces podrı́amos simplemente hacer padding y usar la familia de funciones anterior sin perder la universalidad de la misma.

Planteamos la siguiente familia de funciones de hashing para una clave de longitud l

h(x) = h_int ((sum de(i=1 a l) de) x_i ∗ a^i ) mod p))

p: un número primo grande
a: un número aleatorio entre 0 y p−1
h_int: una función de hashing tomada de la familia universal que definimos anteriormente que recibe un número entre 0 y p − 1 y devuelve otro número entre 0 y m − 1 siendo m nuestro espacio de direcciones.

21
Q

Cuckoo hashing.

A

Se basa en el uso de más de una función de hashing.
Cada función de hashing va a definir una posición alternativa para nuestro dato en una tabla de hash. El algoritmo de búsqueda es muy simple. El dato tiene que estar en alguna de las dos posiciones alternativas o no está en la tabla, es decir, es O(1). La inserción funciona de forma muy sencilla: almacenamos el dato en la posición indicada por la primer función de hashing. Si ese lugar estaba ocupado entonces reubicamos ese dato en su posición alternativa y ası́ sucesivamente, hasta que no hay más datos a reubicar o bien entramos en un loop.

22
Q

Que problemas tiene Cuckoo hashing? Como se solucionan?

A

Es importante estudiar algún mecanismo para detectar si es posible o no dar de alta un nuevo dato sin necesidad de detectar que nuestro algoritmo ha entrado en loop. Para hacer esto, es posible construir un grafo en el cual hay tantos nodos como posiciones en nuestra tabla de hash y por cada dato que insertamos construimos una arista que une las dos posiciones candidatas, indicadas por la función de hashing.

En nuestro grafo cada componente conexo admite un ciclo pero no dos.

23
Q

Explique formas de hacer Cuckoo mas eficiente.

A

El método del Cuckoo puede hacerse más eficiente admitiendo más de un registro por bucket (posición en la tabla de hash) o bien usando 3 funciones de hashing en lugar de 2. Con buckets para 2 registros y 2 funciones de hashing es posible llenar mas de un 90% de la tabla con muy baja probabilidad de que una inserción falle.

La nomenclatura a usar es C_(n,m) en donde n es la cantidad de funciones de hashing a usar y m es la cantidad de registros por bucket. Por ejemplo, en C_(2,8) usamos dos funciones de hashing con buckets que soportan 8 claves cada uno. Varios esquemas de Cuckoo Hashing logran eficiencia cercana al 95% del espacio por lo que podemos generar tablas de hash bastante compactas.

Cuckoo Hashing With a Stash
Cuando una inserción falla una alternativa muy simple es poner el registro en cuestión en un área de overflow o stash. Esto permite que la clave se almacene y que el método continue siendo eficiente. Con áreas de stash relativamente pequeñas el método del Cuckoo puede lograr una eficiencia muy importante. El costo, obvio, es tener que buscar las claves en el Stash en caso de no encontrarlas en las posiciones que indique la función de hashing. Curiosamente, si el tamaño del stash es constante, esto no afecta el orden del algoritmo, ya que O(2) = O(2 + k) siendo k el tamaño del stash una constante.

24
Q

Explique Two-way hashing.

A

Es posible generalizar el método del cuckoo a un esquema genérico en el cual usemos múltiples funciones de hashing. Consideremos primero el caso más simple en el cual tenemos una tabla de hash en donde cada bucket tiene capacidad para k datos. Usando dos funciones de hashing tenemos dos buckets candidatos para cada clave y podemos tomar como heurı́stica almacenar el dato en el bucket que tenga menor cantidad de datos. Este esquema se denomina Two-Way hashing. Es un esquema bastante eficiente y que requiere muy pocos detalles de programación.

25
Q

Defina hashing perfecto.

A

Una función de hashing perfecta es aquella que no tiene colisiones, esto garantiza O(1) para cualquier búsqueda de claves.

26
Q

Que problema viene a solucionar el esquema FKS?

A

Empecemos pensando una forma muy ineficiente de realizar hashing perfecto: usando una tabla de hashing muy grande. Por ejemplo si tenemos m claves a insertar queremos saber cuál deberı́a ser el tamaño de una tabla de hash de forma tal que la probabilidad de una colisión sea menor a 1/2. Haciendo algunas cuentas llegamos a que la tabla debe tener un espacio de direcciones de m 2 . Si llamamos m al espacio de claves y n al espacio de direcciones entonces la probabilidad de una colisión es m/n. Si n = m^2 entonces la probabilidad de una colisión es 1/m, que es lo que queremos.

El problema es que si tenemos 1 millón de claves no podemos tener una tabla de hash con capacidad para 1 billón de datos porque es un desperdicio muy grande de espacio y probablemente no tengamos lugar suficiente.

27
Q

Explique el esquema FKS.

A

La solución a este problema es usar dos funciones de hashing en lo que conocemos como esquema FKS. Nuestra primera función de hashing va a tener un espacio de direcciones que podemos fijar como parámetro, llamémoslo k, siendo k un número primo cercano a m. A efectos de simplificar suponemos k = m.

Cada uno de los k = m buckets apuntados por la primera función de hashing contiene un número que es la cantidad de claves que hashearon a esa posición (m_i), y una segunda función de hashing cuyo espacio de direcciones es (m_i)^2 (o el número primo más cercano a (m_i)^2). Esta función de hashing la tomamos de una familia universal hasta estar seguros de que no tenemos colisiones.

28
Q

Costo temporal y espacial de FKS.

A

El esquema FKS garantiza O(1) para la recuperación de claves y el costo de espacio es 2m.

El costo de la primera tabla es m y el de la segunda es sum(i=0 a m-1 de) (m_i)^2

29
Q

Fallas de FKS.

A

Si se pueden dar de alta y de baja los datos.

30
Q

Como se soluciona la falla de FKS?

A

Hashing perfecto y dinamico.

Si tenemos m claves construimos una función perfecta para 2m claves usando el esquema FKS. Esta sirve hasta que tengamos 2m claves, en cuyo caso reconstruimos la función de hashing para 4m elementos.

Como antes, si tenemos una colisión en la tabla de segundo nivel, simplemente reconstruimos la tabla eligiendo otra función de hashing de nuestra familia H. Esto no ocurre muy seguido por lo que el costo es bajo.

Si eliminamos elementos hasta que tenemos m/4 claves en total, entonces reconstruimos la tabla para m (no para 2m), ya que si borramos lo suficiente podemos reconstruir a la mitad del tamaño.

La posibilidad de mantener una función de hashing perfecta con bajo costo para datos dinámicos es una de las caracterı́sticas más importantes del esquema FKS.

31
Q

Que condiciones posibilitan el uso de hashing perfecto y minimo?

A

Esto sólo es posible cuando conocemos cuáles son todas las claves que queremos almacenar en la tabla y los datos son estáticos. Cuando eso pasa es posible desarrollar una función que mapee cada clave a una única posición de forma tal de no tener colisiones.

32
Q

Explique HDC (Hash, Displace & Compress).

A

Necesitamos una familia de funciones de hashing universales que podamos parametrizar con un número entero h(i, x). Las funciones de esta familia nos generan un número entre 0 y n − 1 que es la cantidad de claves que tenemos.

En un primer paso vamos a hashear todas las claves a una tabla G usando h(0, x) y encadenando los sinónimos. El resultado es una simple tabla de hash con encadenamiento de sinónimos. Vamos a usar un vector de n bits para marcar qué valores ya hemos usado en la construcción de la función de hashing perfecta. Inicialmente este vector está en 0.

En un segundo paso vamos a recorrer esta tabla ordenando los buckets que tengan 2 o más claves, de acuerdo a la cantidad de sinónimos en los mismos de mayor a menor. Es decir, procesamos primero el bucket (lista) con mayor cantidad de colisiones.

Por cada bucket probamos funciones de hashing h(i, x) con i = 1, 2, …, etc hasta encontrar una función que nos distribuya las claves en posiciones que aun no hemos usado para nuestra función de hashing. Notemos que inicialmente no hemos usado ninguna función, por lo que es muy probable que encontremos rapidamente una función de hashing que no produzca colisiones para las claves del primer bucket (frecuentemente h(1, x) funciona). Luego seguimos con el resto de los buckets, teniendo en cuenta que las posiciones que ya hemos usado anteriormente no podemos volver a usarlas. En cada caso, una vez que encontramos la función en la tabla G, ponemos el valor de i que corresponde a la misma.

Luego del segundo paso solo nos quedan los buckets que tienen un solo registro. Estos los vamos a distribuir en las posiciones que quedaron libres simplemente indicando la posición en la tabla G. Para distinguir este caso de algún valor de i, lo vamos a marcar con un número negativo.

La función h(0, x) y la tabla G nos determinan entonces la función de hashing perfecta y mı́nima.

Para buscar una clave usando esta función usamos primero h(0, x). Esto nos da una posición en la tabla G. Accediendo a esta tabla, observamos si el número allı́ almacenado es positivo o negativo. Si es negativo entonces el valor absoluto del mismo nos da el resultado de la función de hashing. Si el número es en cambio positivo, z, el valor de la función de hashing es h(z, x).

33
Q

Como se puede optimizar espacialmente HDC?

A

Este algoritmo puede complementarse comprimiendo los números en la tabla G para que ocupen aun menos espacio, esto es factible ya que en general se trata de números pequeños en el caso de los positivos y de números cuyo valor absoluto es ascendente para los negativos. Aprovechando estas caracterı́sticas podemos usar alguna técnica de compresión de datos para que los números ocupen poco lugar minimizando la cantidad de memoria necesaria para la función de hashing.

34
Q

Cual es el objetivo de hashing consistente?

A

El objetivo es poder determinar dado un dato (clave,valor), en qué equipo debemos almacenar el dato.

35
Q

Explique Hashing consistente.

A

El principio es muy simple. Mapeamos cada máquina de nuestro cluster a un número en el intervalo [0, 1). Esto se puede hacer simplemente hasheando el nombre del equipo y normalizando al intervalo [0, 1). Lo mismo hacemos con nuestras claves. Hasheamos cada clave y normalizamos el resultado a un número en el intervalo [0, 1). El esquema que llamamos ”Hashing Consistente” propuesto en [54] es muy simple: a cada clave se le asigna el número de máquina o servidor que se encuentre inmediatamente a su derecha en el intervalo [0, 1), tomando el intervalo de forma circular.

36
Q

The hashing trick.

A

Me da fiaca ponerlo aca; igual es sencillo.

37
Q

Metodo de Weinberger.

A

En cada dimensiones se suma o resta 1, no solamente suma.

38
Q

Metodo de Weinberger. Que sucede con el producto interno?

A

El efecto más interesante de este método es que el producto interno entre los vectores en nuestra nueva representación es equivalente al producto interno entre los vectores en el espacio original, lo cual admite el uso de THT para crear Hash Kernels en donde usamos el producto interno entre los nuevos vectores para estimar la semejanza entre dos vectores (a mayor producto interno más semejantes son los vectores).

39
Q

Enuncie el teorema de Johnson LIndenstrauss.

A

ara todo conjunto de n datos en d dimensiones y una cierta tasa de error 0 < epsilon < 1 existe un entero positivo k de la forma:

k = 4 log(n) (1)/(eps^2/2 - eps^3/3)

Lo que el teorema nos dice, en definitiva es que es posible representar a los datos en una cantidad de dimensiones en el orden de O(log(n)), siendo n la cantidad de datos, de forma tal que las distancias en el nuevo espacio dimensional sean muy similares a las distancias entre los puntos en el espacio original.