Python 3.2中的Python MD5哈希比较

4

我正在尝试验证从服务器下载的两个文件。第一个文件包含数据,第二个文件包含MD5哈希校验和。

我创建了一个函数,从数据文件返回一个十六进制摘要,如下所示:

def md5(fileName):
    """Compute md5 hash of the specified file"""
    try:
        fileHandle = open(fileName, "rb")
    except IOError:
        print ("Unable to open the file in readmode: [0]", fileName)
        return
    m5Hash = hashlib.md5()
    while True:
        data = fileHandle.read(8192)
        if not data:
            break
        m5Hash.update(data)
    fileHandle.close()
    return m5Hash.hexdigest()

我使用以下方法比较文件:

file = "/Volumes/Mac/dataFile.tbz"
fileHash = md5(file)

hashFile = "/Volumes/Mac/hashFile.tbz.md5"
fileHandle = open(hashFile, "rb")
fileHandleData = fileHandle.read()

if fileHash == fileHandleData:
    print ("Good")
else:
    print ("Bad")

文件比较失败,所以我打印出了fileHashfileHandleData两者的内容,结果如下:
[0] b'MD5 (hashFile.tbz) = b60d684ab4a2570253961c2c2ad7b14c\n'
[0] b60d684ab4a2570253961c2c2ad7b14c

从上面的输出可以看出哈希值是相同的。为什么哈希比较失败了?我是Python的新手,正在使用Python 3.2版本。有什么建议吗?

谢谢。


您没有展示函数或如何打印变量。显然,您展示的值是不同的,但是我们不知道类型(一个是字节字符串的repr(),另一个是十六进制数据)。您可能想要查看http://cfv.sourceforge.net/。 - Yann Vernier
4个回答

1

您正在比较哈希值与fileHandle的内容。您需要去掉MD5(hashFile.tbz)=部分以及结尾的换行符,这样尝试一下:

if fileHash == fileHandleData.rsplit(' ', 1)[-1].rstrip():
    print ("Good")
else:
    print ("Bad")

请注意,在Python 3中,rsplit()rstrip()不支持缓冲API,只能操作字符串。因此,正如Fred Nurk所正确添加的那样,您还需要对fileHandleData/fileHash进行编码/解码(分别是字节缓冲区或(Unicode)字符串)。

1

比较失败的原因与这个语句为假的原因相同:

a = "data"
b = b"blah (blah) - data"
print(a == b)

那个 .md5 文件的格式很奇怪,但如果它总是以那种格式出现,测试的简单方法是:

if fileHandleData.rstrip().endswith(fileHash.encode()):

因为您的fileHash是一个(Unicode)字符串,所以您必须将其编码为字节进行比较。您可能希望指定一个编码而不是使用当前默认的字符串编码。

如果总是期望该确切格式,则最好使用正则表达式提取哈希值并可能检查文件名。

或者更灵活地,您可以测试子字符串的存在:

if fileHash.encode() in fileHandleData:

谢谢你的帮助。我使用了你的建议,并进行了以下修改:if fileHash in fileHandleData.decode("utf-8"):。 - David

0

哈希值是相同的,但字符串不同。您需要获取摘要的十六进制值,并从文件中解析哈希值。一旦完成这些步骤,您就可以将它们进行比较以检查它们是否相等。


我已从摘要中获取了十六进制值。你如何从文件中解析哈希值?你能给个例子吗? - David
从末尾开始切割字符串。 >>> '12345\n'[-3:-1] '45' - Ignacio Vazquez-Abrams

0
尝试使用 "fileHash.strip("\n")... 然后比较两者。这应该可以解决问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接