7

ディレクトリ内のすべてのファイルの md5sum を取得する Python スクリプトを作成しようとしています (Linux)。以下のコードで行ったと思います。

これを実行して、ディレクトリ内のファイルが変更されておらず、削除するファイルが追加されていないことを確認したいと考えています。

問題は、ディレクトリ内のファイルに変更を加えた後、元に戻す場合です。以下の関数を実行すると、別の結果が得られます。(変更したファイルを元に戻しましたが。

誰でもこれを説明できますか。また、回避策を考えられるかどうか教えてください。

def get_dir_md5(dir_path):
    """Build a tar file of the directory and return its md5 sum"""
    temp_tar_path = 'tests.tar'
    t = tarfile.TarFile(temp_tar_path,mode='w')  
    t.add(dir_path)
    t.close()

    m = hashlib.md5()
    m.update(open(temp_tar_path,'rb').read())
    ret_str = m.hexdigest()

    #delete tar file
    os.remove(temp_tar_path)
    return ret_str

編集: これらの素晴らしい人々が答えたように、tarには変更日などのヘッダー情報が含まれているようです。zip を使用すると、別の形式または別の形式で動作しますか?

回避策の他のアイデアはありますか?

4

4 に答える 4

8

他の回答が述べたように、tar メタデータの変更またはファイル順序の変更により、コンテンツが同じであっても、2 つの tar ファイルが異なる場合があります。ファイル データに対してチェックサムを直接実行し、ディレクトリ リストを並べ替えて、それらが常に同じ順序になるようにする必要があります。チェックサムにメタデータを含めたい場合は、手動で含めます。

を使用した未テストの例os.walk:

import os
import os.path
def get_dir_md5(dir_root):
    """Build a tar file of the directory and return its md5 sum"""

    hash = hashlib.md5()
    for dirpath, dirnames, filenames in os.walk(dir_root, topdown=True):

        dirnames.sort(key=os.path.normcase)
        filenames.sort(key=os.path.normcase)

        for filename in filenames:
            filepath = os.path.join(dirpath, filename)

            # If some metadata is required, add it to the checksum

            # 1) filename (good idea)
            # hash.update(os.path.normcase(os.path.relpath(filepath, dir_root))

            # 2) mtime (possibly a bad idea)
            # st = os.stat(filepath)
            # hash.update(struct.pack('d', st.st_mtime))

            # 3) size (good idea perhaps)
            # hash.update(bytes(st.st_size))

            f = open(filepath, 'rb')
            for chunk in iter(lambda: f.read(65536), b''):
                hash.update(chunk)

    return hash.hexdigest()
于 2011-09-06T19:47:14.593 に答える
7

TAR ファイルのヘッダーには、ファイルの変更時刻のフィールドが含まれています。ファイルを変更する行為は、その変更が後で元に戻されたとしても、TAR ファイルのヘッダーが異なることを意味し、異なるハッシュにつながります。

于 2011-09-06T19:30:34.067 に答える
3

提案したことを実行するために TAR ファイルを作成する必要はありません。

回避策のアルゴリズムは次のとおりです。

  1. ディレクトリ ツリーをたどります。
  2. 各ファイルの md5 署名を取得します。
  3. 署名を並べ替えます。
  4. 個々のファイルのすべての署名のテキスト文字列の md5 署名を取得します。

結果として得られる単一の署名が、探しているものになります。

Python も必要ありません。あなたはこれを行うことができます:

find /path/to/dir/ -type f -name *.py -exec md5sum {} + | awk '{print $1}'\
| sort | md5sum
于 2011-09-06T19:38:30.640 に答える
1

tarファイルには、ファイルのアクセス時間、変更時間など、実際のファイルの内容を超えるメタデータが含まれています。ファイルの内容が変更されていなくてもtar、実際にはファイルは異なります。

于 2011-09-06T19:31:35.510 に答える