Una función hash rodante (también conocida como hash recursivo o suma de verificación rodante) es una función hash en la que la entrada se procesa mediante una ventana que se desplaza a través de la entrada.
Algunas funciones hash permiten calcular un hash rodante muy rápidamente: el nuevo valor hash se calcula rápidamente a partir únicamente del valor hash anterior, se elimina el valor anterior de la ventana y se agrega el nuevo valor a la ventana, de forma similar a como se puede calcular una función de promedio móvil mucho más rápido que otros filtros de paso bajo; y de forma similar a como se puede actualizar rápidamente un hash Zobrist a partir del valor hash anterior.
Una de las principales aplicaciones es el algoritmo de búsqueda de cadenas Rabin-Karp , que utiliza el hash rodante descrito a continuación. Otra aplicación popular es el programa rsync , que utiliza una suma de verificación basada en adler-32 de Mark Adler como hash rodante. El sistema de archivos de red de bajo ancho de banda (LBFS) utiliza una huella digital Rabin como hash rodante. FastCDC (Fast Content-Defined Chunking) utiliza una huella digital Gear de alta eficiencia computacional como hash rodante.
En el mejor de los casos, los valores hash rodantes son independientes por pares [ 1 ] o fuertemente universales . No pueden ser independientes por tres , por ejemplo.
Hash rodante polinomial
El algoritmo de búsqueda de cadenas de Rabin-Karp se suele explicar utilizando una función hash rodante que solo emplea multiplicaciones y sumas:
- ,
dóndees una constante, yson los caracteres de entrada (pero esta función no es una huella digital de Rabin , véase más abajo).
Para evitar manipular grandes cantidadesvalores, todas las operaciones matemáticas se realizan módulo. La elección deyes fundamental para obtener un buen hashing; en particular, el móduloes típicamente un número primo . Consulte el generador congruencial lineal para obtener más información.
Eliminar y añadir caracteres simplemente implica sumar o restar el primer o último término. Desplazar todos los caracteres una posición a la izquierda requiere multiplicar la suma completa.porDesplazar todos los caracteres una posición a la derecha requiere dividir la suma total.por. Tenga en cuenta que en aritmética modular,puede elegirse para tener un inverso multiplicativopor cualSe puede multiplicar para obtener el resultado de la división sin realizar realmente una división.
Huella dactilar de Rabin
La huella digital de Rabin es otro hash que también interpreta la entrada como un polinomio, pero sobre el campo de Galois GF(2) . En lugar de ver la entrada como un polinomio de bytes, se ve como un polinomio de bits, y toda la aritmética se realiza en GF(2) (de forma similar a CRC-32 ). El hash es el resto de la división de ese polinomio por un polinomio irreducible sobre GF(2). Es posible actualizar una huella digital de Rabin utilizando solo el byte de entrada y el de salida, lo que la convierte efectivamente en un hash rodante. [ 2 ]
Debido a que comparte el mismo autor que el algoritmo de búsqueda de cadenas de Rabin-Karp, que a menudo se explica con otro hash rodante más simple, y debido a que este hash rodante más simple también es un polinomio, ambos hashes rodantes a menudo se confunden entre sí. [ 3 ]
Polinomio cíclico
El hashing mediante polinomio cíclico [ 4 ] —a veces llamado Buzhash [ 5 ] — también es sencillo y tiene la ventaja de evitar multiplicaciones, utilizando en su lugar un desplazamiento circular . Es una forma de hashing por tabulación : presupone que existe alguna función de sustitución.de caracteres a enteros en el intervalo, esencialmente una tabla de búsqueda (cada una de las 32 posiciones de bits de los valores de s debe estar equilibrada, es decir, tener tantos 1 como 0). Sea la funciónser rotación bit a bit . Por ejemplo,. Dejarsea el OR exclusivo a nivel de bits.sea el i-ésimo byte en un flujo, ysea el tamaño de ventana en uso.
Precalculamospara eliminar la contribución de un byte que está fuera de la ventana: [ 4 ] : Tabla III
Los valores hash se definen como la siguiente relación de recurrencia: [ 4 ] : Tabla III
Todos los valores de H están dentro del intervaloEsta relación de recurrencia describe la forma de calcular el hash de manera continua: [ 4 ] : Tabla III
- El hash se inicializa en 0.
- Cuando se está llenando la ventana, agregar un carácter implica rotar a la izquierda el hash antiguo una posición y aplicar la operación XOR al nuevo..
- Cuando la ventana está llena, se utiliza el mismo procedimiento para agregar un carácter, seguido de la eliminación de la contribución del carácter fuera de la ventana mediante XOR..
El valor de H no es formalmente uniforme ni 2-universal, a pesar de su uniformidad empírica. Sin embargo, puede hacerse formalmente uniforme e independiente por pares si solo se cumple una condición consecutiva.Se toman bits del hash. En la práctica, esto puede ser una operación AND (enmascaramiento) a nivel de bits:, dóndees una operación AND bit a bit yes un desplazamiento a la izquierda. [ 1 ]
Además, los autores de borg señalan que w no debería ser un múltiplo de 2 L si se utiliza una semilla para modificar s[] mediante la operación XOR de cada valor con la semilla. [ 6 ]
Hashing de engranajes
El agrupamiento de engranajes es otro tipo de hash tabulado. Sea s una tabla inmutable de 256 enteros aleatorios sin signo de 32 bits, H el acumulador hash (entero sin signo, de al menos 32 bits) y f el archivo representado como una matriz de bytes (enteros de 8 bits, subíndice basado en 1).sea el operador de desplazamiento a la izquierda. La relación de recurrencia es: [ 7 ]
En comparación con el hash polinomial cíclico, la operación de rotación a la izquierda se reemplaza por un desplazamiento a la izquierda, lo que elimina la necesidad de eliminar la contribución de un byte fuera de la ventana. La operación XOR también se reemplaza por una suma. La segmentación se realiza en función de los bits superiores de H. Este tipo de segmentación genera resultados comparables con la huella digital de Rabin en un tercio del tiempo. [ 7 ] Sin embargo, en la práctica, la distribución de tamaños de división fue más amplia que la de Rabin, lo que hizo que los resultados de deduplicación fueran aproximadamente un 1 % peores para los casos típicos y un 6 % peores para el peor caso. [ 8 ]
El uso de los bits inferiores también es aceptable , pero reduce el tamaño efectivo de la ventana deslizante. El mayor tamaño efectivo aparece cuando la máscara muestrea una serie de bits no consecutivos de un "intervalo" relativamente amplio de H. [ 8 ]
Segmentación basada en contenido mediante un hash rotatorio
Una de las aplicaciones interesantes de la función hash rodante es que puede crear fragmentos dinámicos basados en el contenido de un flujo o archivo. Esto resulta especialmente útil cuando se requiere enviar solo los fragmentos modificados de un archivo grande a través de una red: una simple adición de bytes al principio del archivo normalmente provocaría que todas las ventanas de tamaño fijo se actualizaran, cuando en realidad, solo se ha modificado el primer "fragmento". [ 9 ]
Un enfoque simple para hacer fragmentos dinámicos es calcular un hash rodante, y si el valor hash coincide con un patrón arbitrario (por ejemplo, todos ceros) en los N bits inferiores (con una probabilidad deDado que el hash tiene una distribución de probabilidad uniforme, se elige como límite de un fragmento. Cada fragmento tendrá, por lo tanto, un tamaño promedio debytes. Este enfoque garantiza que los datos no modificados (a más de un tamaño de ventana de distancia de los cambios) tendrán los mismos límites. Una vez que se conocen los límites, los fragmentos deben compararse mediante un valor hash criptográfico para detectar cambios. [ 10 ]
Este tipo de segmentación definida por contenido (CDC) o segmentación basada en contenido (CBC) se utiliza a menudo para la deduplicación de datos . [ 9 ] [ 11 ] La función hash utilizada puede ser cualquier algoritmo de hash rodante. Algunos ejemplos son:
- Agrupación en los fragmentos menos significativos
- Huella digital de Rabin, tal como se utiliza en el software de copia de seguridad restic (con un tamaño de blob que varía entre 512 KiB y 8 MiB y una ventana de 64 bytes). [ 9 ]
- Agrupación en cualquier bit consecutivo
- Polinomio cíclico (buzhash), como el que se usa en el software de copia de seguridad Borg . Borg proporciona un rango de tamaño de fragmento personalizable para dividir flujos de archivos, basado en la variación de N , por defecto entre 512 KiB y 8 MiB ). [ 11 ] Utiliza una ventana de 4095 bytes [ 11 ] y una función de sustitución no balanceada. [ 13 ]
- Fragmentación en cualquier colección de bits
La segmentación basada en contenido tiene la ventaja de que, en la mayoría de los casos, los cambios locales en un archivo solo afectan al fragmento en el que se encuentra y posiblemente al siguiente, pero no a ningún otro. La elección de distintos algoritmos y funciones hash ofrece diferentes niveles de garantía.
Segmentación basada en contenido mediante suma móvil
Varios programas, incluidos gzip (con la --rsyncableopción) y rsyncrypto, realizan un seccionamiento basado en el contenido basado en esta suma móvil específica (no ponderada): [ 12 ]
dónde
- es bytedel archivo,
- es un "valor hash" que consiste en los 12 bits inferiores de la suma de 8196 bytes consecutivos que terminan con el byte.
Desplazar la ventana un byte simplemente implica sumar el nuevo carácter a la suma y restar el carácter más antiguo (que ya no está en la ventana) de la suma. Gracias a las propiedades de la aritmética modular, el almacenamiento requerido es de tan solo 12 bits.
Por cadadónde, estos programas cortan el archivo entrey.
FastCDC
FastCDC optimiza el CDC basado en Gear [ 7 ] principalmente mediante la adición de un bucle de "arranque" para los bytes anteriores al tamaño mínimo deseado. Al omitir la comprobación de corte, se mejora el rendimiento y, además, se añade una función que permite controlar el tamaño mínimo. [ 8 ] El nuevo esquema duplica aproximadamente la velocidad con respecto al antiguo algoritmo basado en Gear y es 10 veces más rápido que el enfoque CDC basado en Rabin. [ 15 ]
El pseudocódigo de la versión básica se proporciona a continuación:
entrada del algoritmo FastCDC : búfer de datos src , longitud de datos n , salida: punto de corte iMinSize ← 2KB // tamaño mínimo de fragmento dividido es 2 KB MaxSize ← 64KB // tamaño máximo de fragmento dividido es 64 KB Mask ← 0x0000d93003530000 // 13 bits activados -> tamaño promedio deseado es 2^13 bytes = 8 KB fp ← 0 // uint64 i ← 0 // El tamaño del búfer es menor que el tamaño mínimo del fragmento. Si n ≤ MinSize , entonces devuelve n. Si n ≥ MaxSize , entonces n ← MaxSize. // Saltar los primeros MinSize bytes y arrancar el hash mientras i < MinSize hacer fp ← ( fp << 1 ) + Gear [ src [ i ]] i ← i + 1 mientras i < n hacer fp ← ( fp << 1 ) + Gear [ src [ i ]] si !( fp & Mask ) entonces devolver i i ← i + 1 regreso i
Donde la matriz Gear es equivalente a la tabla s anterior.
Una versión avanzada utiliza dos máscaras diferentes derivadas de la máscara anterior , una con 15 bits activados y la otra con 11 bits activados. La primera se usa cuando i < 8 KB; posteriormente, se usa la segunda. Esto ajusta la distribución del tamaño de los bloques alrededor del promedio deseado y mejora la deduplicación. [ 8 ]
Complejidad computacional
Todas las funciones hash rodantes se pueden calcular en tiempo lineal para el número de caracteres y actualizar en tiempo constante cuando los caracteres se desplazan una posición. En particular, el cálculo del hash rodante de Rabin-Karp de una cadena de longitudrequiereoperaciones aritméticas modulares y el hash mediante polinomios cíclicos requiereOR exclusivos a nivel de bits y desplazamientos circulares . [ 1 ]
Véase también
Referencias
- 1 2 3 Daniel Lemire, Owen Kaser: El hash recursivo de n -gramas es independiente por pares, en el mejor de los casos, Computer Speech & Language 24 (4), páginas 698–710, 2010. arXiv:0705.4676 .
- ↑ Huellas dactilares mediante polinomios aleatorios. Rabin, M. (1981)
- ↑ "Referencias — documentación de restic 0.9.0" . restic.readthedocs.io . Consultado el 24 de mayo de 2018 .
- 1 2 3 4 Cohen, Jonathan D. (julio de 1997). "Funciones hash recursivas para n-gramas". ACM Transactions on Information Systems . 15 (3): 291– 320. doi : 10.1145/256163.256168 .
- ^ Uzgalis, Robert (1995). "BUZ Hash" .
- ↑ "docs: se agregaron algunas ideas de "Voltara", corrige #903 · ThomasWaldmann/borg@ec93073" . GitHub .
- 1 2 3 4 Xia, Wen; Jiang, Hong; Feng, Dan; Tian, Lei; Fu, Min; Zhou, Yukun (septiembre de 2014). "Ddelta: Un enfoque de compresión delta rápida inspirado en la deduplicación". Performance Evaluation . 79 : 258–272 . doi : 10.1016/j.peva.2014.07.016 .
- 1 2 3 4 Xia, Wen; Zhou, Yukun; Jiang, Hong; Feng, Dan; Hua, Yu; Hu, Yuchong; Liu, Qing; Zhang, Yucheng (2016). FastCDC: Un enfoque de segmentación rápido y eficiente definido por contenido para la deduplicación de datos . Conferencia Técnica Anual USENIX 2016 (ATC '16). Asociación Usenix. ISBN 9781931971300. Consultado el 24 de julio de 2020 .
- 1 2 3 "Fundamentos: Introducción a la segmentación definida por contenido (CDC)" . 2015.
- 1 2 Horvath, Adam (24 de octubre de 2012). "Rabin Karp rolling hash: fragmentos de tamaño dinámico basados en el contenido hash" .
- 1 2 3 "Estructuras de datos y formatos de archivo — Documentación de Borg - Deduplicating Archiver 1.1.5" . borgbackup.readthedocs.io . Consultado el 24 de mayo de 2018 .
- 1 2 "Algoritmo Rsyncrypto" .
- ^ Waldmann, Thomas. "Documentos de borg: ideas/discusión de buzhash" . GitHub .
- ↑ Leeb-du Toit, J. "Introducción a la segmentación definida por contenido" . joshleeb.com .
- ↑ Xia, Wen; Zou, Xiangyu; Jiang, Hong; Zhou, Yukun; Liu, Chuanyi; Feng, Dan; Hua, Yu; Hu, Yuchong; Zhang, Yucheng (16 de junio de 2020). "El diseño de fragmentación rápida definida por contenido para sistemas de almacenamiento basados en deduplicación de datos". Transacciones IEEE en sistemas paralelos y distribuidos . 31 (9): 2017– 2031. Bibcode : 2020ITPDS..31.2017X . doi : 10.1109/TPDS.2020.2984632 . S2CID 215817722 .
Enlaces externos
- MIT 6.006: Introducción a los algoritmos 2011 - Sesión 9 - Hash rotatorio
- Funciones hash