Проверка целостности файла python

Проверка целостности файла с помощью Python

У меня есть каталог со многими большими файлами. Все они созданы с помощью этой строки кода:

pickle.dump(variable, gzip.open(file_name, 'wb'), -1) 

Таким образом, они представляют собой сжатые, сериализованные переменные.

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

Итак, во-первых, я предполагаю, что если что-то неожиданное произошло, есть возможность иметь file_name в файловой системе, которая повреждена, и не содержит (по крайней мере, полностью) сжатую сериализованную variable . Я здесь?

Теперь я задаюсь вопросом, есть ли способ проверить целостность этих файлов, не загружая их в память один за другим. Я пытаюсь избежать выполнения pickle.load(gzip.open(file_name, ‘rb’)) с помощью try/except .

Это возможно? Есть ли другой (более быстрый) способ проверить, успешно ли pickle и gzip успешно завершены?

Хотя я не думаю, что можно проверить правильность файла gzip, кроме его распаковки, протокол маринованных данных содержит код операции STOP который должен присутствовать в конце всех маринованных данных. (Если он отсутствует, разблокировка вызовет EOFError ). Этот стоп-код операции – это . персонаж. Таким образом, вы можете частично проверить правильность рассола, проверив, заканчивается ли оно . персонаж. Это также означает, что вы можете объединить два подходящих соленых огурца, а затем распечатать результат дважды, чтобы получить два объекта. Все соленые огурцы в протоколе два или выше также начинаются с \x80 ( € ).

Благодаря ответу @ppperry я нашел решение, которое быстрее, чем де-сериализация всего в памяти.

f = gzip.open(file_name, 'rb') f.seek(-1, os.SEEK_END) f.read(1) == bytes('.', 'utf8') 
  • Во второй строке может произойти сбой, если сжатый файл некорректен (используйте try/except ).
  • Третья строка – та, которая читает последний байт, который должен быть . ,
Читайте также:  Birthday Reminders for August

Я использую следующий метод в python 2.6. В Python 2.7 вы можете использовать с

try: f = gzip.open(filepath, 'rb') f._read_gzip_header() return True except Exception, e: print e return False finally: f.close() 

Источник

Как проверить целостность файлов с помощью дайджеста в Python (SHA256SUMS)

У меня есть набор файлов и SHA256SUMS дайджест-файл, содержащий sha256() хеш для каждого из файлов. Как лучше всего проверить целостность моих файлов с помощью Python?

Например, вот как я могу загрузить сетевой установщик Debian 10 SHA256SUMS дайджест-файл и загрузите / проверьте его MANIFEST файл в BASH

[email protected]:~$ wget http://ftp.nl.debian.org/debian/dists/buster/main/installer-amd64/current/images/SHA256SUMS --2020-08-25 02:11:20-- http://ftp.nl.debian.org/debian/dists/buster/main/installer-amd64/current/images/SHA256SUMS Resolving ftp.nl.debian.org (ftp.nl.debian.org). 130.89.149.21, 2001:67c:2564:a120::21 Connecting to ftp.nl.debian.org (ftp.nl.debian.org)|130.89.149.21|:80. connected. HTTP request sent, awaiting response. 200 OK Length: 75295 (74K) Saving to: ‘SHA256SUMS’ SHA256SUMS 100%[===================>] 73.53K 71.7KB/s in 1.0s 2020-08-25 02:11:22 (71.7 KB/s) - ‘SHA256SUMS’ saved [75295/75295] [email protected]:~$ wget http://ftp.nl.debian.org/debian/dists/buster/main/installer-amd64/current/images/MANIFEST --2020-08-25 02:11:27-- http://ftp.nl.debian.org/debian/dists/buster/main/installer-amd64/current/images/MANIFEST Resolving ftp.nl.debian.org (ftp.nl.debian.org). 130.89.149.21, 2001:67c:2564:a120::21 Connecting to ftp.nl.debian.org (ftp.nl.debian.org)|130.89.149.21|:80. connected. HTTP request sent, awaiting response. 200 OK Length: 1709 (1.7K) Saving to: ‘MANIFEST’ MANIFEST 100%[===================>] 1.67K --.-KB/s in 0s 2020-08-25 02:11:28 (128 MB/s) - ‘MANIFEST’ saved [1709/1709] [email protected]:~$ sha256sum --check --ignore-missing SHA256SUMS ./MANIFEST: OK [email protected]:~$ 

Как лучше всего выполнить ту же операцию (загрузите и проверьте целостность Debian 10 MANIFEST файл с помощью SHA256SUMS файл) в питоне?

3 ответа

Следующий скрипт python реализует функцию с именем integrity_is_ok() что ведет к SHA256SUMS файл и список файлов для проверки, и он возвращает False если какой-либо из файлов не может быть проверен и True иначе.

#!/usr/bin/env python3 from hashlib import sha256 import os # Takes the path (as a string) to a SHA256SUMS file and a list of paths to # local files. Returns true only if all files' checksums are present in the # SHA256SUMS file and their checksums match def integrity_is_ok( sha256sums_filepath, local_filepaths ): # first we parse the SHA256SUMS file and convert it into a dictionary sha256sums = dict() with open( sha256sums_filepath ) as fd: for line in fd: # sha256 hashes are exactly 64 characters long checksum = line[0:64] # there is one space followed by one metadata character between the # checksum and the filename in the `sha256sum` command output filename = os.path.split( line[66:] )[1].strip() sha256sums[filename] = checksum # now loop through each file that we were asked to check and confirm its # checksum matches what was listed in the SHA256SUMS file for local_file in local_filepaths: local_filename = os.path.split( local_file )[1] sha256sum = sha256() with open( local_file, 'rb' ) as fd: data_chunk = fd.read(1024) while data_chunk: sha256sum.update(data_chunk) data_chunk = fd.read(1024) checksum = sha256sum.hexdigest() if checksum != sha256sums[local_filename]: return False return True if __name__ == '__main__': script_dir = os.path.split( os.path.realpath(__file__) )[0] sha256sums_filepath = script_dir + '/SHA256SUMS' local_filepaths = [ script_dir + '/MANIFEST' ] if integrity_is_ok( sha256sums_filepath, local_filepaths ): print( "INFO: Checksum OK" ) else: print( "ERROR: Checksum Invalid" ) 
[email protected]:~$ wget http://ftp.nl.debian.org/debian/dists/buster/main/installer-amd64/current/images/SHA256SUMS --2020-08-25 22:40:16-- http://ftp.nl.debian.org/debian/dists/buster/main/installer-amd64/current/images/SHA256SUMS Resolving ftp.nl.debian.org (ftp.nl.debian.org). 130.89.149.21, 2001:67c:2564:a120::21 Connecting to ftp.nl.debian.org (ftp.nl.debian.org)|130.89.149.21|:80. connected. HTTP request sent, awaiting response. 200 OK Length: 75295 (74K) Saving to: ‘SHA256SUMS’ SHA256SUMS 100%[===================>] 73.53K 201KB/s in 0.4s 2020-08-25 22:40:17 (201 KB/s) - ‘SHA256SUMS’ saved [75295/75295] [email protected]:~$ wget http://ftp.nl.debian.org/debian/dists/buster/main/installer-amd64/current/images/MANIFEST --2020-08-25 22:40:32-- http://ftp.nl.debian.org/debian/dists/buster/main/installer-amd64/current/images/MANIFEST Resolving ftp.nl.debian.org (ftp.nl.debian.org). 130.89.149.21, 2001:67c:2564:a120::21 Connecting to ftp.nl.debian.org (ftp.nl.debian.org)|130.89.149.21|:80. connected. HTTP request sent, awaiting response. 200 OK Length: 1709 (1.7K) Saving to: ‘MANIFEST’ MANIFEST 100%[===================>] 1.67K --.-KB/s in 0s 2020-08-25 22:40:32 (13.0 MB/s) - ‘MANIFEST’ saved [1709/1709] [email protected]:~$ ./sha256sums_python.py INFO: Checksum OK [email protected]:~$ 

Части приведенного выше кода были адаптированы из следующего ответа на Ask Ubuntu:

Источник

Проверка целостности tarfile в Python

Я работаю над преобразованием моего резервного скрипта из оболочки в Python. Одной из особенностей моего старого скрипта было проверить целостность созданного tarfile, выполнив: gzip -t.

Это кажется немного сложным в Python.

Похоже, что единственный способ сделать это — прочитать каждый из сжатых объектов TarInfo внутри tar-файла.

Есть ли способ проверить целостность tar-файла, не извлекая его на диск или не сохраняя его в памяти (полностью)?

Хорошие люди на #python на freenode предложили мне читать каждый объект TarInfo по частям, отбрасывая каждую прочитанную часть чанка.

Я должен признать, что понятия не имею, как это сделать, видя, что я только начал Python.

Представьте, что у меня есть tarfile размером 30 ГБ, содержащий файлы размером от 1 КБ до 10 ГБ.

Это решение, которое я начал писать:

try: tardude = tarfile.open("zero.tar.gz") except: print "There was an error opening tarfile. The file might be corrupt or missing." for member_info in tardude.getmembers(): try: check = tardude.extractfile(member_info.name) except: print "File: %r is corrupt." % member_info.name tardude.close() 

Этот код далеко не закончен. Я бы не посмел запустить это на огромном архиве tar размером 30 ГБ, потому что в какой-то момент проверка была бы объектом размером 10+ ГБ (если у меня есть такие огромные файлы в архиве tar)

Бонус: я попытался вручную испортить zero.tar.gz (редактор шестнадцатеричных файлов — отредактировать несколько байтов в середине файла). Первый кроме IOError не ловит. Вот вывод:

Traceback (most recent call last): File "./test.py", line 31, in for member_info in tardude.getmembers(): File "/usr/lib/python2.7/tarfile.py", line 1805, in getmembers self._load() # all members, we first have to File "/usr/lib/python2.7/tarfile.py", line 2380, in _load tarinfo = self.next() File "/usr/lib/python2.7/tarfile.py", line 2315, in next self.fileobj.seek(self.offset) File "/usr/lib/python2.7/gzip.py", line 429, in seek self.read(1024) File "/usr/lib/python2.7/gzip.py", line 256, in read self._read(readsize) File "/usr/lib/python2.7/gzip.py", line 320, in _read self._read_eof() File "/usr/lib/python2.7/gzip.py", line 342, in _read_eof hex(self.crc))) IOError: CRC check failed 0xe5384b87 != 0xdfe91e1L 

Источник

Оцените статью