确定是否已在目录中添加,删除或修改任何文件

Gre*_*reg 7 python md5 tar hashlib tarfile

我正在尝试编写一个Python脚本,它将获取目录中所有文件的md5sum(在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
Run Code Online (Sandbox Code Playgroud)

编辑: 正如这些优秀的人已经回答,看起来tar包括标题信息,如修改日期.使用zip工作会有什么不同或其他格式吗?

还有其他的解决方法吗?

Ros*_*ron 8

正如提到的其他答案一样,即使内容由于tar元数据更改或文件顺序更改而相同,两个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()
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案.我概述的相同基本方法,但在代码中.尼斯. (2认同)

Joe*_*Joe 7

TAR文件头包括用于文件的修改时间的字段; 更改文件的行为,即使稍后更改了该更改,也意味着TAR文件头将不同,从而导致不同的哈希值.