即使数据已编码,Python 散列与 hashlib 也会抛出错误怎么修?

问题描述

我有一个函数可以计算目录中所有文件的哈希值。作为其中的一部分,打开每个文件,读取块,并更新哈希:

import hashlib,os

def get_dir_hash(directory,verbose=0):
    hash = hashlib.sha256()
    if not os.path.exists(directory):
        return -1

    try:
        for root,dirs,files in os.walk(directory):
            for names in files:
                if verbose == 1:
                    print(f"Hashing {names}")

                filepath = os.path.join(root,names)
                try:
                    f1 = open(filepath,'rb')
                except:
                    # You can't open the file for some reason
                    if f1 is not None:
                        f1.close()
                    continue

                while 1:
                    # Read file in as little chunks
                    buf = f1.read(4096)
                    if not buf:
                        break
                    hash.update(hashlib.sha256(str(buf).encode('utf-8')).hexdigest())

                if f1 is not None:
                    f1.close()

    except:
        import traceback
        # Print the stack traceback
        traceback.print_exc()
        return -2

    return hash.hexdigest()

请注意,我读取了一大块字节,转换为字符串,然后按照 SO 中其他答案的建议编码为 utf-8:

hash.update(hashlib.sha256(str(buf).encode('utf-8')).hexdigest())

但是,我仍然收到此错误

Traceback (most recent call last):
  File "/home/user/Work/mmr6/mmr/util/dir_hash.py",line 33,in get_dir_hash
    hash.update(hashlib.sha256(str(buf).encode('utf-8')).hexdigest())
TypeError: Unicode-objects must be encoded before hashing

我错过了什么?

解决方法

我找到了你遗漏的东西:
当你写 hash.update(hashlib.sha256(str(buf).encode('utf-8')).hexdigest())
带有 str(buf).encode('utf-8') 的部分有点无用,因为您可以直接编写 buf(它已经是 对象)
但是 hashlib.sha256(buf).hexdigest() 返回一个 str 实例,因此这就是错误的来源。
该行的固定版本是

hash.update(hashlib.sha256(buf).hexdigest().encode("utf-8"))

我不是 100% 确定这是否是您想要做的,请随时告诉我