The Rolling Hash

Lecture



A rolling (sliding, circular) hash, rolling hash — is a hash function that processes input within some window. Computing the hash function’s value for a shifted window is a cheap operation for such functions. To recompute the value, one only needs to know the previous hash value, the value of the input data that fell outside the window, and the value of the data that entered the window. In other words, if The Rolling Hash is the hash of the sequence The Rolling Hash, then the hash The Rolling Hash for the “shifted” sequence The Rolling Hash can be obtained using an easily computable function The Rolling Hash.

The ability to quickly “shift” the hash imposes certain limits on the theoretical guarantees. In particular, it has been shown that families of rolling hashes cannot be 3-independent[en]; at best — universal or 2-independent[en]. However, for most applications (even approximate) universality is sufficient.

One of the main applications is the Rabin–Karp string search algorithm, which uses the rolling hash described below. The rolling hash is used for substring search in the Rabin—Karp algorithm, for computing hashes of N-grams in text , and also in the rsync program for comparing binary files (a rolling version of adler-32 is used).

Another popular application is the rsync program, which uses a checksum based on Mark Adler’s adler-32 as a rolling hash. The Low-Bandwidth File System (LBFS) uses a Rabin fingerprint as its rolling hash. FastCDC (Fast Content-Defined Chunking) uses a computationally efficient Gear fingerprint as its rolling hash.

In the best case, rolling hash values are pairwise independent or strongly universal. For example, they cannot be 3-independent.

Polynomial hash

The Rabin—Karp algorithm often uses a simple polynomial rolling hash built from multiplication and addition operations :

The Rolling Hash.

To avoid using arbitrary-precision integer arithmetic, arithmetic is performed in the ring of residues modulo The Rolling Hash, which fits into a single machine word. The choice of the constants The Rolling Hash and The Rolling Hash is very important for obtaining a good-quality hash. In the original version of the hash, it was assumed that The Rolling Hash should be a randomly chosen prime number, and The Rolling Hash. However, since the algorithm for choosing a random prime is not so simple, a variant of the hash is preferred in which The Rolling Hash is a fixed prime number and The Rolling Hash is chosen randomly from the range The Rolling Hash. Dietzfelbinger et al. showed that this variant of the hash has the same theoretical properties as the original. In particular, the probability that the hash values of two different strings The Rolling Hash and The Rolling Hash collide does not exceed The Rolling Hash, provided that The Rolling Hash and The Rolling Hash are integers from the range The Rolling Hash, and The Rolling Hash and The Rolling Hash are chosen truly at random.

Removing old input symbols and adding new ones is done by adding or subtracting the first or last term of the formula (modulo The Rolling Hash). To remove the term The Rolling Hash, a precomputed value The Rolling Hash is stored. The window is shifted by multiplying the entire polynomial The Rolling Hash by The Rolling Hash or dividing by The Rolling Hash (if The Rolling Hash is prime, then in the ring of residues one can multiply by the inverse instead of dividing). In practice it is most convenient to take The Rolling Hash or The Rolling Hash for 32-bit and 64-bit machine words respectively (these are the so-called Mersenne primes). In this case the modulo operation can be performed on many computers using fast bitwise shift and addition operations . Another possible choice — the values The Rolling Hash or The Rolling Hash, for which fast algorithms for taking the remainder modulo The Rolling Hash also exist (in this case the range of allowed values of The Rolling Hash is narrowed slightly) . A common misconception — assuming The Rolling Hash. There exist families of strings for which a hash with The Rolling Hash will always produce many collisions, regardless of the choice of The Rolling Hash. These and other further implementation and theoretical-analysis details of the polynomial hash can be found in the article on the Rabin—Karp algorithm.

Polynomial hash over the field GF(2L)

This hash is similar to the ordinary polynomial hash, but all computations in it are carried out in the finite field The Rolling Hash. Usually The Rolling Hash is chosen to be 64. The elements of the field — these are the numbers The Rolling Hash. Addition in the field is implemented using the bitwise exclusive “or” operation The Rolling Hash, and multiplication is performed using the operation The Rolling Hash, which first carrylessly multiplies[en] The Rolling Hash by The Rolling Hash, and then takes the remainder of the “carryless” division of the result by some chosen fixed element The Rolling Hash (carryless division here is the operation inverse to carryless multiplication). The element The Rolling Hash must be chosen so that The Rolling Hash and The Rolling Hash — is an irreducible polynomial over the field The Rolling Hash (the field The Rolling Hash is often viewed as the set of polynomials over the field The Rolling Hash modulo some arbitrary irreducible polynomial of degree The Rolling Hash). For instance, one can set The Rolling Hash . Then the hash is computed as follows :

The Rolling Hash,

where The Rolling Hash — a number randomly chosen during hash initialization from the range The Rolling Hash, and The Rolling Hash — a short notation for The Rolling Hash, where The Rolling Hash is repeated The Rolling Hash times. Using the fundamental theorem of algebra, it can be shown that the probability of a collision between the hashes of two different strings of length The Rolling Hash does not exceed The Rolling Hash. It has been shown that on modern Intel and AMD processors, all the arithmetic over the field The Rolling Hash needed for the hash can be efficiently computed using instructions from the CLMUL[en] extension.

Cyclic polynomial hashing (Buzhash)

Let The Rolling Hash — be some hash that maps the characters The Rolling Hash of the string being hashed to The Rolling Hash-bit numbers (usually The Rolling Hash or The Rolling Hash). Cyclic polynomial hashing is defined as follows :

The Rolling Hash

where The Rolling Hash — the bitwise exclusive “or” operation, and The Rolling Hash — the operation of a cyclic left shift of the The Rolling Hash-bit number The Rolling Hash by The Rolling Hash bits. It is easy to show that this hash is rolling:

The Rolling Hash

The main advantage of this hash is that it uses only fast bitwise operations available on most modern computers. The quality of the hash depends directly on the choice of the function The Rolling Hash. Lemire and Kaser proved that if the function The Rolling Hash is chosen randomly from a family of independent hash functions[en], then the probability that the hashes of two different strings of length The Rolling Hash collide does not exceed The Rolling Hash. This imposes certain restrictions on the range of problems in which this hash can be used. First, the length of the strings being hashed must be less than The Rolling Hash. For general-purpose hashing algorithms this condition can be a problem, but, for instance, for hashing The Rolling Hash-grams, where The Rolling Hash usually does not exceed 16, this restriction is natural (in the case of The Rolling Hash-grams, the role of the characters is played by individual tokens of the text). Second, the choice of a family of independent functions The Rolling Hash can also be a problem in some cases. For a byte alphabet, the property of independence is possessed by the family of functions The Rolling Hash, encoded by a table of 256 different random The Rolling Hash-bit numbers (choosing the function — filling in the table). For hashing The Rolling Hash-grams, one can assign different random The Rolling Hash-bit numbers to different tokens (the number of distinct tokens in such tasks is usually relatively small), and such a family of hash functions The Rolling Hash also has the independence property.

Rabin hash

This hash is applicable only in the special case where the characters of the string being hashed The Rolling Hash are the numbers 0 and 1. The idea of the hash is to view the input string The Rolling Hash as a polynomial The Rolling Hash over the field The Rolling Hash, and the hash itself is the remainder of dividing The Rolling Hash by an irreducible polynomial The Rolling Hash of degree The Rolling Hash over the field The Rolling Hash, chosen randomly during hash initialization. Essentially this is the same procedure used in CRC. Let us examine it in more detail.

The result of hashing the string The Rolling Hash — this is the sequence of bits The Rolling Hash. The number The Rolling Hash is chosen to be prime and large enough, but such that the sequence The Rolling Hash fits into a single machine word (usually The Rolling Hash or The Rolling Hash is taken). Let The Rolling Hash be some irreducible polynomial of degree The Rolling Hash over the field The Rolling Hash. Denote by The Rolling Hash the corresponding number with bit representation The Rolling Hash. The hash function The Rolling Hash is defined as the number with bit representation The Rolling Hash such that the polynomial The Rolling Hash is the remainder of dividing the polynomial The Rolling Hash by the polynomial The Rolling Hash, that is, The Rolling Hash.

Despite its rather convoluted definition, the Rabin hash is fairly simple to implement (once the irreducible polynomial The Rolling Hash has already been found). The computation relies on the following simple observation: if the number The Rolling Hash with bit representation The Rolling Hash encodes the polynomial The Rolling Hash, then the number The Rolling Hash encodes the polynomial The Rolling Hash, where The Rolling Hash denotes the operation of shifting the number The Rolling Hash one bit to the left, filling the low-order bit with zero (not to be confused with the cyclic shift The Rolling Hash defined above!). Let The Rolling Hash, and The Rolling Hash — this is the bit representation of The Rolling Hash. Then The Rolling Hash is computed as follows:

The Rolling Hash if The Rolling Hash

The Rolling Hash if The Rolling Hash

The hash is rolling. Let The Rolling Hash, and The Rolling Hash — this is the bit representation of The Rolling Hash. The hash The Rolling Hash is computed as follows :

The Rolling Hash if The Rolling Hash

The Rolling Hash if The Rolling Hash

where The Rolling Hash — this is the The Rolling Hash-bit number whose bit representation corresponds to the polynomial The Rolling Hash. The number The Rolling Hash is precomputed when initializing the hash for a string of length The Rolling Hash.

The main difficulty — randomly choosing an irreducible polynomial The Rolling Hash of degree The Rolling Hash. Rabin described an efficient algorithm for doing this, and proved that the probability of a collision between the hashes of two different strings of length The Rolling Hash, for a random choice of The Rolling Hash, does not exceed The Rolling Hash.

Note that this hash is often confused with the polynomial hash, owing to their similar area of application, their common use of polynomials, and a shared author.

Content-defined chunking using a rolling hash [ edit ]

One interesting use of a rolling hash function is that it can be used to create dynamic blocks based on the content of a stream or file. This is especially useful when only the changed portions of a large file need to be sent over the network, since simply adding a byte at the start of the file would cause all the fixed-size windows to be updated, whereas in fact only the first "chunk" was changed.

The simplest approach to computing dynamic fragments is to compute the rolling hash, and if it matches a pattern (for example, all of the low-order N bits are zero), then that is a fragment boundary. This approach guarantees that any change to the file will affect only its current and, possibly, the next fragment, but nothing else.

Once the boundaries are known, the blocks must be compared by their hash values to determine which of them has changed and needs to be sent over the network. The Attic backup program uses the Buzhash algorithm with a configurable block-size range to split file streams.

Content-defined chunking using a rolling sum

Several programs, including gzip (with the --rsyncable option) and rsyncrypto, perform content-defined chunking based on this particular (unweighted) rolling sum:

The Rolling Hash

The Rolling Hash

where

  • The Rolling Hash is the sum of 8196 consecutive bytes ending with byte The Rolling Hash (requires 21 bits of memory),
  • The Rolling Hash is byte The Rolling Hash of the file,
  • The Rolling Hash the "hash value", consisting of the low 12 bits of The Rolling Hash.

Shifting the window by one byte simply involves adding the new character to the sum and subtracting the oldest character (no longer within the window) from the sum.

For every The Rolling Hash where The Rolling Hash, these programs split the file between The Rolling Hash and The Rolling Hash. This approach guarantees that any change to the file will affect only its current and, possibly, the next fragment, but not any other fragment.

Gear device fingerprint and the FastCDC content-defined chunking algorithm

The Content-Defined Chunking (CDC) algorithm must compute the hash value of the data stream byte by byte and split the data stream into fragments when the hash value matches a predefined value. However, comparing the string byte by byte leads to significant computational overhead. FastCDC proposes a new and efficient approach to Content-Defined Chunking. It uses the fast Gear hashing algorithm , skipping a minimum length, normalizing the distribution of fragment sizes, and, last but not least, rolling two bytes at a time to speed up the CDC algorithm, which achieves roughly 10 times greater throughput than the Rabin-based CDC approach.

Pseudocode for the basic version is given below:

  The Rolling Hash

Here, the Gear array is a precomputed hashing array. FastCDC uses the Gear hashing algorithm, which can quickly compute rolling-hash results and maintain a uniform distribution of hash results, just as Rabin’s does. Compared with the traditional Rabin hashing algorithm, it provides much higher speed. Experiments show that when segmenting a data stream, it can generate almost the same distribution of fragment sizes in much less time (about 1/10 of the time of the Rabin-based approach ).

Computational complexity

All rolling hash functions are linear in the number of characters, but their complexity, which depends on the window length (The Rolling Hash), varies. The Rabin–Karp rolling hash requires multiplying two The Rolling Hash-bit numbers, an integer multiplication in The Rolling Hash. [10] Hashing n-grams with cyclic polynomials can be done in linear time.

See also

  • Hash function
  • w-shingling

Comments

To leave a comment

If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Lectures and tutorial on "Information security, Cryptographic ciphers"

Terms: Information security, Cryptographic ciphers