Алгоритм определения идентичности файлов (Оптимизация)

В дополнение к этому вопросу: Алгоритм определения идентичности файлов

Recap. Я ищу дешевый алгоритм определения идентичности файлов, который работает в большинстве случаев.

Я пошел вперед и реализовал алгоритм, который дает мне "довольно уникальный" хеш для каждого файла.

Как работает мой алгоритм:

  • Для файлов, меньших определенного порога, я использую полный файл для хеширования идентификаторов.

  • Для файлов, больших порога, я беру случайные N выборок размера X.

  • Я включаю файлы в хешированные данные. (что означает, что все файлы разных размеров приводят к другому хэшу)

Вопросы:

  • Какие значения я должен выбрать для N и X (сколько случайных выборок следует взять с каким размером?) Я пошел с 4 образцами по 8 К каждый и не умею пнуть алгоритм. Я обнаружил, что увеличение количества выборок быстро снижает скорость алгоритма (потому что поиски довольно дороги)

  • Математика одна: как не разные мои файлы должны быть для того, чтобы этот алгоритм взорвался. (2 разных файла с одинаковой длиной в конечном итоге имеют одинаковый хэш)

  • Оптимизация: Есть ли способ, которым я могу оптимизировать свою конкретную реализацию для повышения пропускной способности (я, кажется, способен делать около 100 файлов в секунду в моей системе).

  • Является ли эта реализация понятной? Можете ли вы подумать о каких-либо реальных примерах мира, где это провалится. (Мое внимание сосредоточено на медиафайлах)

Соответствующая информация:

Алгоритм, который я реализовал

Спасибо за вашу помощь!

Ответ 1

  • Всегда включать 1-й и последний блок файла в хэш.

Это потому, что они скорее всего будут отличаться от файла к файлу. Если вы рассматриваете BMP, у него может быть довольно стандартный заголовок (например, изображение 800x600, 24 бит, нулевой остаток), поэтому вам может потребоваться немного превысить заголовок, чтобы получить данные дифференцирования. Проблема в том, что заголовки сильно различаются по размеру.

Последний блок для файловых форматов, которые добавляют данные к оригиналу.

  • Читайте в блоках размера, которые являются родными для используемой файловой системы или, по крайней мере, делятся на 512.
  • Всегда читать блоки со смещением, которые делятся на блокировки.
  • Если вы получаете то же самое для файла того же размера, выполните глубокое сканирование его (хешировать все данные) и запомните путь к файлу, чтобы не сканировать его снова.

Даже если вам повезет, вы ошибочно определите некоторые файлы (например, файл базы данных SQL Server и резервную копию 1:1 после нескольких вставок, за исключением того, что SS пишет метку времени).

Ответ 2

Я бы избегал такого решения. Я практикую, что может быть почти невозможно, чтобы два медиафайла имели одинаковый размер и одни и те же данные на соответствующих позициях для сжатых форматов. Но если вам приходится иметь дело с несжатыми изображениями или волновыми файлами, вероятность того, что небольшие локальные изменения не обнаружены, растет.

Итак, я думаю, что вы должны реально хэш файл. Хотя это кажется дорогим, может быть, нет, если у вас есть доступ ко всем файлам - например, если вы создаете файловый сервер или что-то в этом роде. Вы можете наращивать хэш.

Если вы видите новый файл с уникальной длиной файла, просто сохраните длину файла. Если добавлен другой файл с одинаковой длиной, вычислить хэши обоих файлов по блоку, пока они не будут отличаться. Сохраните длину файла, хэш и сколько блоков файла включены в хеш. Всякий раз, когда вы обнаруживаете совпадающие длины файлов и хэши, и вы еще не хэшировали весь файл, вы расширяете хеш, добавляя больше блоков.

Некоторые мысли о производительности. Для небольших файлов шансы равной длины файла довольно высоки - не так много разной длины файла. Но это не дорого для небольших файлов хэша.

Для больших файлов шансы на сжатие файлов долгое время снижаются, так как есть все больше и больше возможных длин файлов. Для файлов с различными медиафайлами шансы очень хорошие, что они отличаются непосредственно за заголовком, поэтому вам нужно будет хэшировать только короткую часть начала файла.

Наконец, вы обязательно обнаружите разные файлы (за исключением хеш-коллизий), потому что при необходимости вы получите хэш файл.

UPDATE

Для фильмов я считаю, что длина файла практически уникальна, но файлы, перекодированные для размещения на определенном носителе, вероятно, отображают эту идею. void - (S) VCD-фильмы будут находиться в небольшом диапазоне длин файлов около емкости CD-ROM.

Но для файлов фильмов в целом я бы просто хэшировал один блок (может быть, 512 байт) из середины файла. Два разных фильма с одним и тем же изображением и звуком в одном и том же положении? Практически невозможно, кроме того, вы манипулируете файлами, чтобы провалить этот тест. Но вы можете легко генерировать файлы для отказа от всех детерминированных стратегий выборки - так что это не имеет большого значения.

Ответ 3

  • Не искать назад и открывать файл с FILE_FLAG_SEQUENTIAL_SCAN (в Windows).
    (Выберите X случайных чисел, затем отсортируйте их).
  • Чтобы искать далеко, в кэше, читаемом вперед, есть некоторые данные.
  • Если у вас есть большие файлы, формат вашего раздела имеет большой размер сектора.
  • Вы возвращаете Guid для Id, для алгоритмов Must has требуется более 128 бит.