Está en la página 1de 13

Universidad Autónoma

Juan Misael Saracho


Alumnos: Antonio Albizu
Ana Priscila Rios

Docente: Deysi Arancibia

Materia: Programación

BÚSQUEDA POR TRANSFORMACIÓN DE CLAVES (HASH)

Grupo: 4 INTRODUCCIÓN

El método hash consiste en facilitar la forma de encontrar los datos en los arreglos En
consecuencia, las aplicaciones h(k), a las que desde ahora llamaremos funciones hash,
tienen la particularidad de que podemos esperar que h( ki ) = h( kj ) para bastantes pares
distintos ( ki,kj ). El objetivo será pues encontrar una función hash que provoque el
menor número posible de colisiones (ocurrencias de sinónimos), aunque esto es solo un
INTRODUCCIÓN
El método hash consiste en facilitar la forma de encontrar los datos en los arreglos En
consecuencia, las aplicaciones h(k), a las que desde ahora llamaremos funciones hash, tienen
la particularidad de que podemos esperar que h(ki ) = h( kj ) para bastantes pares distintos (
ki,kj ). El objetivo será pues encontrar una función hash que provoque el menor número
posible de colisiones (ocurrencias de sinónimos), aunque esto es solo un aspecto del
problema, el otro será el de diseñar métodos de resolución de colisiones cuando éstas
se produzcan.
Se trata de abordar de forma sencilla este concepto para aquellos que no lo conozcan.
Podemos decir que un HASH no es más que un número o resumen. De hecho, esta es
solo una herramienta más que se puede implementar a los arreglos, se puede decir
que un fichero es como un flujo de bits y le aplicamos un algoritmo de HASH lo que
obtenemos es otro conjunto de bits (de longitud fija y que depende del número de bits
de salida del algoritmo o función que utilicemos) que depende bit a bit del contenido
del flujo original de bits que sirvió como entrada al algoritmo.
Además, cumplen las siguientes propiedades:
• Todos los Hashes generados con una función de hash tienen el mismo tamaño, sea
cual sea el mensaje utilizado como entrada.
• Dado un mensaje, es fácil y rápido mediante un ordenador calcular su HASH.
• Es imposible reconstruir el mensaje original a partir de su HASH.
• Es imposible generar un mensaje con un HASH determinado.
Es decir, un algoritmo de HASH no es un algoritmo de encriptación, aunque sí se utiliza
en esquemas de cifrado, como algoritmos de cifrado asimétrico (por ejemplo, en el
RSA).

BÚSQUEDA POR TRANSFORMACIÓN DE CLAVES (HASH)


Este método permite asignar a un valor una posición determinada de un arreglo y de
igual forma permite recuperarla fácilmente, igualmente convierte una clave dada en una
dirección (índice), dentro del arreglo.
Además, gracias a que no hay necesidad de tener los elementos ordenados aumenta la
velocidad de búsqueda. Cuenta también con la ventaja de que el tiempo de búsqueda
es prácticamente independiente del número de componentes del arreglo.

Para trabajar con este método de búsqueda debe elegirse previamente:

1. Una función hash que sea fácil de calcular y que distribuya uniformemente las
claves.
2. Un método para resolver colisiones. Si estas se presentan se debe contar con
algún método que genere posiciones alternativas

Uso de funciones Hash:

2
1. proteger la confidencialidad de una contraseña
2. garantizar la integridad de los datos
3. verificar la identidad del emisor de un mensaje mediante firmas digitales

La eficiencia de una función Hash depende de:

1. La distribución de los valores de llave o clave que realmente se usan.


2. El número de valores de llave o clave que realmente están en uso con respecto
al tamaño del espacio de direcciones.
3. El número de registros que pueden almacenarse en una dirección dada sin causar
una colisión.
4. La técnica usada para resolver el problema de las colisiones.

ALGORITMO HASHING
Algoritmo que se utiliza para generar un valor de Hash para algún dato, como por
ejemplo claves. Un algoritmo de Hash hace que los cambios que se produzcan en los
datos de entrada provoquen cambios en los bits del Hash. Gracias a esto, los Hash
permiten detectar si un dato ha sido modificado. (Vilugron, 2014)

Ventajas Desventajas

Se pueden usar los valores naturales de la No pueden usarse registros de longitud


llave, puesto que se traducen internamente variable.
a direcciones fáciles de localizar.
El archivo no está clasificado.
Se logra independencia lógica y física,
debido a que los valores de las llaves son
independientes del espacio de direcciones. No permite claves repetidas.

No se requiere almacenamiento adicional Solo permite acceso por una sola llave.
para los índices.

• Costos

➢ Tiempo de procesamiento requerido para la aplicación de la función Hash.


➢ Tiempo de procesamiento y los accesos E/S requeridos para solucionar las
colisiones.

TABLAS HASH
Las tablas hash son estructuras tipo vector que ayudan a asociar claves con valores o
datos.
Observación:

3
No se debe buscar directamente el valor deseado, sino a través de una función de
dispersión h(x) localizar la posición del valor buscado. (Olmos, 2014)

Una tabla hash se construye con tres elementos básicos:

1. Un vector capaz de almacenar “m” elementos


2. Función de dispersión que permita a partir de los datos (llamados clave) obtener
el índice donde estará el dato en el arreglo
3. Una función de resolución de colisiones

Olmos, (2014). Tablas hash. Recuperado de


http://www.cs.buap.mx/~iolmos/ada/TablasHashArbolesBinario
s.pdf

Para el diseño de una tabla hash, es de gran importancia cumplir con lo siguiente:

➢ Función sencilla para una evaluación rápida


➢ Distribuir uniformemente en el espacio de almacenamiento
➢ Evitar (si es posible) la aparición de sinónimos o colisiones
➢ Para dos claves similares, generar posiciones distantes

Tipos de Tablas Hash


Existen diferentes tipos de tablas hash:

Tablas de dirección directa: cuando el Tablas de dirección indirecta: Cuando el universo de


universo de objetos objetos U es muy grande, se crea un vector T de
dimensión m, tal que |U| > m
U es relativamente pequeño
Elemento con llave k →almacenado en el slot h(k)
Elemento con llave k →almacenado en el slot k |U| > m → ∃ ki, kj ∈U: h(ki) = h(kj) ←COLISIONES 4
MÉTODOS DE TRANSFORMACIÓN DE CLAVES
Existen numerosos métodos de transformación de claves. Todos ellos tienen en común
la necesidad de convertir claves en direcciones.
Cuando se desea localizar un elemento de clave x, el indicador de direcciones indicará
en qué posición del array estará situado el elemento.

Función Módulo (Por División)


Se lo utiliza cuando la distribución de los valores de claves no es conocida.
La función de este método es dividir el valor de la clave entre un número apropiado, y
después utilizar el residuo de la división como dirección relativa para el registro. (Castro,
2014)
Suponga que se tiene un arreglo de N elementos y K es la clave del dato a buscar.
La función hash queda:
H(k) = (K mod N) +1
Para lograr una mayor uniformidad en la distribución, N debe ser un número primo. (El
número primo próximo a N)
Existen varios factores que deben considerarse para seleccionar el divisor:
➢ divisor > n: suponiendo que solamente un registro puede ser almacenado en una
dirección relativa dada.
➢ Seleccionarse el divisor de tal forma que la probabilidad de colisión sea
minimizada.
Por ejemplo:
Sea N=100, el tamaño del arreglo
Sus direcciones de 1-100.
Sea K1 = 7259
K2 = 9359
Dos claves que deban asignarse posiciones en el arreglo
H(K1) = (7259 mod 100) +1=60
H(K2) = (9359 mod 100) +1=60
Donde H(K1) es igual a H(K2) y K1 es distinto de K2, es una colisión
Se aplica N igual a un valor primo en lugar de utilizar N=100
H(K1) = (7259 mod 97) +1=82
H(K2) = (9359 mod 97) +1=48
Con N=97 se ha eliminado la colisión

5
Truncamiento
El truncamiento consiste en tomar algunos dígitos de la clave y con estos formar una
posición en un array. Se ignora parte de la clave para con el resto formar un índice de
almacenamiento.
La idea consiste en tener un listado de números, seleccionar por ejemplo la posición 2,
4 y 5; para así tener una posición en donde poder almacenar la clave. Llevando esto a
un ejemplo práctico.
5700931 703
3498610 481
0056241 064
9134720 142
5174829 142

Lo positivo del truncamiento y una de las ventajas por sobre otros métodos de
búsqueda y ordenamiento es que no solo funciona con valores numéricos, también
funciona con caracteres alfabéticos, esto se puede aplicar de dos formas:
1) Transformar cada carácter en un número asociado a su posición en el
abecedario.
2) Transformar cada carácter en un número asociado a su valor según el código
ASCII.

Una vez obtenida la clave en forma numérica, se puede utilizar normalmente.


La elección de los dígitos a considerar es arbitraria, pueden tomarse posiciones pares
o impares. Luego se les puede unir de izquierda a derecha o de derecha a izquierda.
La función queda definida por:
H(K)=dígitos(t1 t2 t3… tn)+1
Existen casos en los que a la clave generada se les agrega una unidad, esto es para los
casos en el que el vector de almacenamiento tenga valores entre 1 y el 100, así se evita
la obtención de un valor 0.
H(K1)=dígitos(7 2 5 9)+1=76
H(K2)=dígitos(9 3 5 9)+1=96
Una de las principales desventajas de utilizar truncamiento y en sí el método de
hashing es que dos o más claves pueden tomar una misma posición dentro de la tabla
de hash, a esto es a lo que se le llama Colisión. Cuando hay colisiones se requiere de un
proceso adicional para encontrar la posición disponible para la clave, lo cual disminuye
la eficiencia del método.

6
MÉTODOS DE TRATAMIENTO DE COLISIONES

La elección de un método adecuado para resolver colisiones es tan importante como


la elección de una buena función hash. Cuando la función hash obtiene una misma
dirección para dos claves diferentes, se está ante una colisión.

Algunos métodos más utilizados para resolver colisiones son los siguientes:

• Reasignación
• Arreglos anidados
• Áreas de desborde

Reasignación

Existen varios métodos que trabajan bajo el principio de comparación y reasignación


de elementos. Se analizarán tres de ellos:

• Prueba lineal
• Prueba cuadrática
• Doble dirección hash

Prueba Cuadrática
Este método es similar al de la prueba lineal. La diferencia consiste en que en el
cuadrático las direcciones alternativas se generan como D + 1, D + 4, D + 9, . . ., D + i² en
vez de D + 1, D + 2,...,D + i. “La principal desventaja de este método es que pueden
quedar casillas del arreglo sin visitar”. (Takeyas, 2012)
Además, como los valores de las direcciones varían en 1² unidades, resulta difícil
determinar una condición general para detener el ciclo. Este problema podría
solucionarse empleando una variable auxiliar, cuyos valores dirijan el recorrido del
arreglo de tal manera que garantice que serán visitadas todas las casillas. A
continuación, se presenta un ejemplo que ilustra el funcionamiento:

7
Este método se genera a partir de la elevación de un valor al cuadrado, donde ese
valor inicia con el número 1 y lo suma a la dirección que se encuentra en colisión (d+i 2),
si se genera nuevamente una colisión el valor del número se incrementa, se eleva al
cuadrado y se suma a la dirección inicial (d+1, d+4, d+9, d+16, …, d+i2), este proceso se
repite hasta que se encuentre una dirección vacía. “Está generación de direcciones
puede llegar a exceder el tamaño de la estructura, si es así, la dirección inicia en uno y
el valor inicial a elevar es el cero”. (Takeyas, 2012)
Este método es similar al de la prueba lineal. La diferencia consiste en que, en lugar
de buscar en las posiciones con direcciones: dir_Hash, dir_Hash + 1, dir_Hash + 2,
dir_Hash + 3, .... { buscamos linealmente en las posiciones con direcciones: dir_Hash,
dir_Hash + 1, dir_Hash + 4, dir_Hash + 9, ..., dir_Hash+i 2 { Si el número m de
posiciones en la tabla T es un número primo y el factor de carga no excede del 50%,
sabemos que siempre insertaremos el nuevo elemento X y que ninguna celda será
consultada dos veces durante un acceso.

Desventaja:
• Pueden quedar casillas sin visitar, además resulta difícil definir una condición
general para detener el ciclo.

• Se puede utilizar una variable auxiliar, que dirija el recorrido de tal forma que
garanticen que serán visitadas todas las casillas. (Fidalgo., 2013)

Ejemplo:
V=[25, 43, 56, 35, 54, 13, 80, 104, 55]
Usando la función hash:
H(K)= (k mod 10) + 1

Prueba Cuadrática (V, N ,K)

{Este algoritmo busca el dato con clave K en el arreglo V de N elementos. Resuelve el problema de las
colisiones por medio de la prueba cuadrática}
{ D, DX e I son variables de tipo entero}
1. D=H[K] {Genera dirección}
2. Si (V[D] == K) entonces
Escribir “El elemento esta en la posición D”
Si no
2
Hacer I = 1 y DX = D + I ;
2.1 Repetir mientras (V[DX] <> K) y (V[DX]<>VACÍO)
2
Hacer I = I + 1; DX = D + I ;
2.1.1 Si (DX > N)
Entonces Hacer I=0; DX=1 y D=1;
2.1.2 {Fin del paso 2.1.1}
2.2{fin del ciclo del paso 2.1}
2.3 Si (V[DX] == K) entonces
Escribir “El elemento esta en la posición DX”
Si no

8
Escribir “El elemento no está en el arreglo”
2.4{ Fin del condicional del paso 2.3}
3 {Fin del condicional del paso 2}
Código. Prueba Cuadrática.
public static int pruebaCuadratica(int X, int[] A){
int m = A.length;
int dirHash = X%m;
if (A[dirHash] == X) return dirHash;
else {
int i = 1;
int cont = 0;
int dirReh = (dirHash + 1)%m;
while ((A[dirReh] != X) && (A[dirReh] != 0) && (cont < m*10))
{
i++;
dirReh = (dirHash + (i*i))%m;
cont++;
}
if (A[dirReh] == X) return dirReh;
else return -1;
}
}

La doble dirección hash


Consiste en generar otra dirección hash, una vez que se detecta la colisión, la
generación de la nueva dirección se hace a partir de la dirección previamente obtenida
más uno. La función hash que se aplique para generar la nueva dirección puede no ser
la misma a la utilizada en el proceso anterior, para esto no existe una regla establecida,
lo que permite utilizar cualquiera de las funciones hash conocidas hasta ahora.
“En este método se debe generar otra dirección aplicando una función hash H2 a la
dirección previamente obtenida”. (Fidalgo., 2013) Entonces buscamos linealmente en
las posiciones que se encuentran a una distancia H 2(X), 2 H 2(X), 3 H 2(X), ... {La
función hash H 2 que se aplique a las sucesivas direcciones puede ser o no ser la misma
que originalmente se aplicó a la clave. No existe una regla que permita decidir cuál
será la mejor función a emplear en el cálculo de las sucesivas direcciones. Pero una
buena elección sería H 2(X) = R – (X%R), siendo R un número primo más pequeño que

9
el tamaño del array. Y se obtienen unos resultados mejores cuando el tamaño del
array es un número primo

Ejemplo:
V=[25, 43, 56, 35, 54, 13, 80, 104]
H(K)= (k mod 10) +1

Doble Dirección(V, N ,K)

{Este algoritmo busca el dato con clave K en el arreglo V de N elementos. Resuelve el problema de las
colisiones por medio de la doble dirección hash}
{ D y DX son variables de tipo entero}
1. D=H[K] {Genera dirección}
2. Si (V[D] == K) entonces
Escribir “El elemento esta en la posición D”
Si no
Hacer DX = H’ (D);
2.1 Repetir mientras (DX <=N) y (V[DX]<> K) y (V[DX]<>VACÍO) y (DX<>D)
Hacer DX = H’ (DX) ;
2.2{fin del ciclo del paso 2.1}
2.3 Si (V[DX] == K) entonces
Escribir “El elemento esta en la posición DX”
Si no
Escribir “El elemento no está en el arreglo”
2.4{ Fin del condicional del paso 2.3}
3 {Fin del condicional del paso 2}

Código. Doble dirección Hash.


public static int dobleDireccionamiento(int X, int R, int[] A){
int m = A.length;
int dirHash = X%m;
if (A[dirHash] == X) return dirHash;
else {

10
int dirHash2 = R – (X%R);
int i = 1;
int dirReh = (dirHash + dirHash2)%m;
while ((A[dirReh] != X) && (A[dirReh] != 0) )
{
i++;
dirReh = (dirHash + i*dirHash2)%m;
}
if (A[dirReh] == X) return dirReh;
else return -1;
}
}

Arreglos Anidados
Arreglos anidados Este método consiste en que cada elemento del arreglo tenga otro
arreglo en el cual se almacena los elementos colisionados. Si bien la solución parece
ser sencilla, es claro también que resulta ineficiente. Al trabajar con arreglos se
depende del espacio que se halla asignado a este lo cual conduce a un nuevo problema
difícil de solucionar: elegir un tamaño adecuado de arreglo que permita el equilibrio
entre el coste de memoria y el número de valores colisionados que pudiera almacenar.
(fernandez, 2010)

En cada elemento del arreglo tenga otro arreglo, donde se almacenan los elementos
colisionados
1. Solución ineficiente
2. costo de memoria
3. Número de valores colisionados

11
Ejemplo:
V = [25, 43, 56, 35, 54, 13, 80, 104]
Usando la función hash:
H(K)= (k mod 10) +1
80 - - - - - - 43 54 25 56 - - - - - 13 104 35 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

80 - - - -

- - - - -

- - - - -

43 13 - - -

54 104 - - -

25 35 - - -

56 - - - -

- - - - -

- - - - -

- - - - -

Encadenamiento
Cada elemento del arreglo tiene un apuntador a una lista ligad, la cual se ira generando
e ira almacenando los valores colisionados. (takeyas, 2012)
Es un método eficiente debido al dinamismo de las listas
DESVENTAJAS
➢ Ocupa un espacio adicional al de la tabla
➢ Requiere un manejo de lista ligada
➢ Si la lista crece demasiado se pierde el acceso directo del método hash
Ejemplo:
V=[ 25, 43, 56, 35, 54, 13, 80, 104 ]
Almacenados usando la función hash:
H(K)= (k mod 10) +1

12
CONCLUSIONES
• Una tabla hash es una estructura de datos que soporta la recuperación,
eliminación e inserción de elementos de forma muy rápida.
• Las tablas hash permiten que el coste medio de las operaciones insertar, buscar
y eliminar sea constante, siempre que el factor de carga no sea excesivo para
reducir la probabilidad de colisión.
• Una función hash debe ser fácilmente calculable, sin costosas operaciones,
también debe tener una buena distribución de valores entre todas los
componentes de la tabla.
• Una buena función hash distribuye equitativamente la asignación de claves a
través de las posiciones de la tabla hash.
• Si la función está mal diseñada producirá muchas colisiones.
• La fortaleza de una función hash requiere que estas colisiones sean las mínimas
posibles y que encontrarlas sea lo más difícil posible.
RECOMENDACIONES
• Tome en cuenta los requisitos para elaborar una buena tabla hash.
• Escoja el tipo de tabla adecuado para nuestro algoritmo.
• Trate de que el número de colisiones sea casi nulo.
• En caso de que existan colisiones opte por el método de tratamiento más
adecuado para su algoritmo.

13

También podría gustarte