Editorial for COCI '13 Contest 6 #5 Hash
Submitting an official solution before solving the problem yourself is a bannable offence.
This requires a "meet-in-the-middle" attack: it's a common idea in crypto, but is also useful in a number of exponential-time competition problems. For , we can't consider all words separately. However, we can consider five-letter prefixes and five-letter suffixes, and then figure out how to match them up. For each prefix, we can compute its hash, and store a table for how frequently each such hash occurs. For each suffix, we can compute what the hash of the prefix would need to be for the final hash to be , and then use the table to find the number of prefixes that match this suffix. To compute what the hash would need to be, we work backwards: assume the final hash is , and then remove one letter at a time from the end.
Let us observe an iteration of the stated hash function with the assumption that the current value of the hash is and the ordinal number of the next letter is .
We will try to get the value of the previous state when we know the current state and the ordinal number of the letter which got us to the state .
Given the fact that we can look at the operation remainder when dividing with a power of two () as discarding any bits after the , it is easily noticed that the following holds:
Therefore,
because the bitwise XOR is inverse to itself and will always be smaller than , this is also true:
The modular multiplicative inverse of in the field of size will exist if and are relatively prime. Since is a power of two, this condition is true. The modular inverse can be obtained using extended Euclid's algorithm, fast exponentiation or with brute force because is small enough.
Let us display the complete inverse relation of the hash function:
Having inverse relation in place, meet in the middle attack is done which gives us a time complexity of .
Comments