Уже немного поздно, и я не могу думать прямо, поэтому мой расчет сложности алгоритма отчасти не верен :) Но если вам удастся поместить его в память, у вас может быть очень очень быстрая реализация с . Если вы можете оптимизировать каждый узел trie, чтобы он занимал как можно меньше памяти, он может просто работать.
Другое дело, по сути, предложение @ rwmnau, но не используйте предопределенные хеш-функции, такие как MD5 - используйте промежуточные итоги. В отличие от хэшей, это почти бесплатно, без каких-либо недостатков для такого большого размера блока (много случайностей в 4096 байтах). С каждым новым блоком вы получаете один байт и теряете один байт. Итак, вычислите сумму первых 4096 байтов; для каждого последующего просто вычтите потерянный байт и добавьте новый. В зависимости от размера целого числа, в которое вы вносите суммы, у вас будет много сегментов. Тогда у вас будет гораздо меньшее количество блоков для сравнения побайтно.