This concatenates two 64-bit fingerprints. It is a convenience function to get a fingerprint for a combination of already fingerprinted components. For example this code is used to concatenate the hashes from each of the features on sparse crosses. One shouldn't expect FingerprintCat64(Fingerprint64(x), Fingerprint64(y)) to indicate anything about FingerprintCat64(StrCat(x, y)). This operation is
| 66 | // for everything as it is vulnerable to length-extension attacks and it |
| 67 | // is easier to compute multicollisions. |
| 68 | inline uint64 FingerprintCat64(const uint64 fp1, const uint64 fp2) { |
| 69 | static const uint64 kMul = 0xc6a4a7935bd1e995ULL; |
| 70 | uint64 result = fp1 ^ kMul; |
| 71 | result ^= internal::ShiftMix(fp2 * kMul) * kMul; |
| 72 | result *= kMul; |
| 73 | result = internal::ShiftMix(result) * kMul; |
| 74 | result = internal::ShiftMix(result); |
| 75 | return result; |
| 76 | } |
| 77 | |
| 78 | // This is a portable fingerprint interface for strings that will never change. |
| 79 | // However, it is not suitable for cryptography. |