在python中为目录创建唯一的哈希

时间:2016-03-24 15:40:50

标签: python hash

我想在python中为给定目录创建一个唯一的哈希。感谢下面代码的zmo为目录中的每个文件生成一个哈希,但我如何聚合这些哈希以生成一个哈希来表示该文件夹?

import os
import hashlib

def sha1OfFile(filepath):
    sha = hashlib.sha1()
    with open(filepath, 'rb') as f:
        while True:
            block = f.read(2**10) # Magic number: one-megabyte blocks.
            if not block: break
            sha.update(block)
        return sha.hexdigest()

for (path, dirs, files) in os.walk('.'):
  for file in files:
    print('{}: {}'.format(os.path.join(path, file),       
sha1OfFile(os.path.join(path, file)))

2 个答案:

答案 0 :(得分:4)

正确的做法(可能)是为每个目录重复计算哈希值:

import os
import hashlib

def sha1OfFile(filepath):
    sha = hashlib.sha1()
    with open(filepath, 'rb') as f:
        while True:
            block = f.read(2**10) # Magic number: one-megabyte blocks.
            if not block: break
            sha.update(block)
        return sha.hexdigest()

def hash_dir(dir_path):
    hashes = []
    for path, dirs, files in os.walk(dir_path):
        for file in sorted(files): # we sort to guarantee that files will always go in the same order
            hashes.append(sha1OfFile(os.path.join(path, file)))
        for dir in sorted(dirs): # we sort to guarantee that dirs will always go in the same order
            hashes.append(hash_dir(os.path.join(path, dir)))
        break # we only need one iteration - to get files and dirs in current directory
    return str(hash(''.join(hashes)))

仅使用os.walk顺序中的文件的问题(如Markus所做的那样)是您可以为包含相同文件的不同文件结构获取相同的哈希值。例如,这个dir的哈希

main_dir_1:
    dir_1:
        file_1
        file_2
    dir_2:
        file_3

和这个人

main_dir_2:
    dir_1:
        file_1
    dir_2:
        file_2
        file_3

将是相同的。

另一个问题是你需要保证文件的顺序总是一样的 - 如果你以不同的顺序连接两个哈希并计算你得到的字符串的哈希值,你将得到相同目录结构的不同结果。 / p>

答案 1 :(得分:2)

继续将数据输入sha对象。

import os
import hashlib

def update_sha(filepath, sha):
    with open(filepath, 'rb') as f:
        while True:
            block = f.read(2**10) # Magic number: one-megabyte blocks.
            if not block:
                break
            sha.update(block)

for (path, dirs, files) in os.walk('.'):
    sha = hashlib.sha1()
    for file in files:
        fullpath = os.path.join(path, file)
        update_sha(fullpath, sha)

    print(sha.hexdigest())

或者哈希文件的连接哈希值。