md5 или sha1 при копировании файла

md5 или sha1 при копировании файла

Есть ли в каком-либо дистрибутиве Linux способ выполнить проверку md5sum или sha1 во время передачи файла с локального раздела на раздел NFS?

Пример:

У меня есть смонтированный диск NFS и очень большой файл на локальном диске. Я хотел бы перенести этот файл на смонтированный диск NFS и в то же время выполнить проверку md5. Я нашел много скриптов, которые выполняли бы проверку md5 после копирования файла на удаленный диск, но поскольку это очень большой файл, 100 ГБ+, я хотел бы узнать, есть ли способ воспользоваться тем фактом, что файл уже проверяется во время передачи.

решение1

Я не знаю стандартной утилиты Linux, которая может это сделать. Если файл поместится в кэше на основе памяти, не будет таким уж неэффективным сначала выполнить md5sum, а затем скопировать (копия получит данные из памяти).

Вы можете использовать следующую комбинацию:

cat filename | tee remote_output_name | md5sum

который вы могли бы изменить, чтобы напрямую проверить сумму, напечатанную с помощью md5sumсохраненного md5. Это считывает файл с диска только один раз.

Предполагая, что вы сгенерировали check.md5с помощью

cd dir_with_big_files
md5sum * > check.md5

, следующая программа Python будет копировать и проверять один файл, читая/записывая по 64 Мб за раз. Сохраните его как /usr/local/bin/chkcopy chmod +x /usr/local/chkcopyи вызовите его с помощьюchkcopy file_name check.md5 destination_filename_or_dir

#! /usr/bin/env python

import sys, os, hashlib

m = hashlib.md5()
file_name = sys.argv[1]
md5_name = sys.argv[2]
out_name = sys.argv[3]
if os.path.isdir(out_name):
    out_name = os.path.join(out_name, file_name)
BUF_SIZE = 64 * (1024 ** 2)

with open(file_name, 'rb') as ifp:
    with open(out_name, 'wb') as ofp:
        buf = ifp.read(BUF_SIZE)
        while buf:
            m.update(buf)
            ofp.write(buf)
            buf = ifp.read(BUF_SIZE)
with open(md5_name) as fp:
    for line in fp:
        md5, fn = line.rstrip().split('  ', 1)
        if fn == file_name:
            assert m.hexdigest() == md5
            break
    else:
        print('no md5 found for ' + file_name)

решение2

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

Оба инструмента могут выполнять хеширование (даже с несколькими типами хеширования одновременно, если это необходимо) во время копирования. Хэши могут быть рассчитаны по фрагментам и/или по всему потоку данных.

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

Чтобы скопировать файл частями по 8 МБ и вычислить MD5-сумму всех данных, которая выводится в STDERR:

dcfldd if=/path/to/input bs=8M hash=md5 of=/path/to/outputfile

Чтобы скопировать файл блоками по 8 МБ, вычисляя хеш SHA256 всех данных плюс сумму SHA256 для каждого блока по 64 МБ:

dcfldd if=/path/to/input bs=8M hash=SHA256 hashwindow=64M of=/path/to/outputfile

Выходной файл для вычисленного хеша также может быть предоставлен путем указания файла через hashlogпараметр. При вычислении нескольких хешей отдельные выходные данные могут быть указаны через eg md5log=FILE1.log sha256log=FILE2.log.

решение3

Вы можете использовать внешнюю программу ( crcsum), которая расширяет cpи mvс контрольной суммой:

https://sourceforge.net/projects/crcsum/

Связанный контент