TGViewer
Python Заметки Python Заметки @pythonotes · 2.2K subscribers
Post #265 1.72K
На самом деле архивы TAR оказались менее удобными в нашей теме проверки идентичности. Давайте сделаем всё тоже самое для ZIP.

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

import zipfile

def create_zip(archive_path, files):
with zipfile.ZipFile(archive_path, "w") as zf:
for file in files:
zf.write(file)

create_zip('archive1.zip', files_to_archive)
create_zip('archive2.zip', files_to_archive)

Проверим хеш
>>> hashlib.md5(open("archive1.zip", "rb").read()).hexdigest()
'd54670be5e01e483797ee4ae30089423'
>>> hashlib.md5(open("archive2.zip", "rb").read()).hexdigest()
'd54670be5e01e483797ee4ae30089423'

Отлично! ZIP создаёт одинаковые архивы и сразу выдаёт одинаковую хеш-сумму!
Ну всё, на этом расходимся...


Хотя подождите ка, часто ли вы проверяете один и тот же файл на идентичность?
Давайте имитируем ситуацию когда файл был перезаписан или "модифицирован" но при этом фактически не изменился. То есть изменились только его атрибуты. Для этого можно использовать Linux-команду touch, которая обновляет время последнего доступа к файлу.

touch example_file0.txt
touch example_file1.txt
...

Либо альтернативу на Python

from pathlib import Path
for f in files_to_archive:
Path(f).touch()

Содержимое файлов не изменилось! Но изменились атрибуты. Пересоздаём второй архив.

create_zip('archive2.zip', files_to_archive)

Проверяем

>>> hashlib.md5(open("archive1.zip", "rb").read()).hexdigest()
'd54670be5e01e483797ee4ae30089423'
>>> hashlib.md5(open("archive2.zip", "rb").read()).hexdigest()
'aa508dbba4e223abe45e16dba4ad6e1f'

Вот это более правдивая ситуация.

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

def get_hash_zip(path):
hash_md5 = hashlib.md5()
with zipfile.ZipFile(path, "r") as z:
for f_name in z.namelist():
with z.open(f_name) as f:
hash_md5.update(f.read())
return hash_md5.hexdigest()

Сравним теперь хеш-суммы архивов

>>> get_hash_zip('archive1.zip')
'0b27c443737b0a84381b827e1d9a913b'
>>> get_hash_zip('archive2.zip')
'0b27c443737b0a84381b827e1d9a913b'

Всё чётко сработало!
А что по времени?

>>> timeit.timeit("get_hash_zip('archive1.zip')", number=100, globals=globals())
10.8

Ну тоже неплохо.

⭐️ А теперь самая главная фишка ZIP - при создании архива он СРАЗУ записывает контрольную сумму файла в заголовки!
А это значит что мы можем просто считать готовые хеш-суммы и сравнить их! Это называется CRC (cyclic redundancy check)

def get_hash_zip2(path):
h = hashlib.md5()
for info in zipfile.ZipFile(path).infolist():
h.update(info.CRC.to_bytes(8, byteorder='big'))
return h.hexdigest()

>>> timeit.timeit("get_hash_zip2('archive1.zip')", number=100, globals=globals())
0.008

То есть даже буфер никакой не считывается, только несколько байт из заголовков каждого файла. Выполняется моментально. В моем случае 100 итераций за 8 мс!

🌐 Полный листинг тестов в Jupyter (для экспериментов жмём Open in Colab)
📌 И просто в Gists

#libs #tricks
Telegram Python Заметки Для проверки целостности или идентичности файлов всегда используется проверка контрольной суммы. Это работает в большинстве случаев, но не всегда. Давайте сделаем простой тест. Создадим несколько рандомных файлов import os # create random test files files_to_archive…
More from @pythonotes
  1. Sep 21, 2026­ WebAssembly это мощная технология позволяющая загружать практически любое приложение в б…
  2. Aug 17, 2026Не так давно столкнулся с API который в ответе с ошибкой присылал только статус-код. Без п…
  3. Jul 20, 2026У меня основная ОС это Linux. Но нередко требуется делать сборку клиента под Windows. Соби…
  4. Jul 13, 2026В прошлый раз был пример с понижением привелегий процесса. Проблема в том, что обратно под…
  5. Jul 6, 2026Модуль pwd может использоваться для считывания информации о пользователях из базы данных п…
  6. Jun 22, 2026Недавно я реализовал Multi Tenancy систему на FastAPI + SQLAlchemy и пересобрал её в небол…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →