2010-12-16 79 views
1

有人可以给我一个理由,为什么我得到同一个文件的替代沙发?但每秒钟都一样?替换不同的同一个文件的内容。为什么?

>>> f = open('480p.m4v')  
>>> sha1 = str(hashlib.sha224(str(f)).hexdigest()) 
>>> sha1 
'4aa8cf11b849b77f608302fdcdad3703dce54c33ba4bac80fa0ef700' 
>>> f.close() 
>>> f = open('480p.m4v') 
>>> sha2 = str(hashlib.sha224(str(f)).hexdigest()) 
>>> f.close() 
>>> sha2 
'ae60e45200c960f79d25049ef0135709ca6edf246b3f9e53cd084e58' 
>>> f = open('480p.m4v') 
>>> sha3 = str(hashlib.sha224(str(f)).hexdigest()) 
>>> f.close() 
>>> sha3 
'4aa8cf11b849b77f608302fdcdad3703dce54c33ba4bac80fa0ef700' 
>>> f = open('480p.m4v') 
>>> sha4 = str(hashlib.sha224(str(f)).hexdigest()) 
>>> f.close() 
>>> sha4 
'ae60e45200c960f79d25049ef0135709ca6edf246b3f9e53cd084e58' 
>>> f = open('480p.m4v') 
>>> sha5 = str(hashlib.sha224(str(f)).hexdigest()) 
>>> f.close() 
>>> sha5 
'4aa8cf11b849b77f608302fdcdad3703dce54c33ba4bac80fa0ef700' 
>>> f = open('480p.m4v') 
>>> sha6 = str(hashlib.sha224(str(f)).hexdigest()) 
>>> f.close() 
>>> sha6 
'ae60e45200c960f79d25049ef0135709ca6edf246b3f9e53cd084e58' 

回答

8

你得到不同散列的原因是因为你没有真正散列文件的内容,只有文件对象的字符串表示。例如:

>>> f = open('480p.m4v') 
>>> print str(f) 
<open file '480p.m4v', mode 'r' at 0x0224C9D0> 

您会注意到对象的地址在不同实例之间明显改变,导致哈希值发生变化。很明显,一个文件对象的内存位置被每创建一个其他实例重用,导致哈希值重合。

若要散列文件的内容,您可以使用此:

>>> sha = str(hashlib.sha224(f.read()).hexdigest()) # read() slurps the whole file into a string 
+0

使用'f.read()'代替。 – katrielalex 2010-12-16 20:01:32

+0

@katrielalex:是的,只是添加它。谢谢 – Cameron 2010-12-16 20:03:30

+0

谢谢你们。就是这样。 – aschmid00 2010-12-16 20:52:31

2

str(f)不给你的文件的内容,它会返回类似:

"<open file '480p.m4v', mode 'r' at 0xb7855230>" 

我不知道为什么这样交替,虽然。

+0

嗯,如果'0xb7855230'是一个地址,也许它会改变如果'str(f)'读取每次都变成一个不同的地址,那么'沙'会有所不同? – FrustratedWithFormsDesigner 2010-12-16 20:01:58

+0

“open”函数评估,创建一个新文件。它存储在'f'中。如果覆盖'f',先前指向的'f'被破坏,释放特定内存位置的空间。该位置是打开文件所需的确切大小,因此下次调用open时会使用该位置。 – robert 2010-12-16 20:02:03

+0

+1至于为什么它交替:可能是因为CPython的堆管理讨厌的内部。 (Python 3使用不同的repr,不包括id - 每次给出相同的str;非常令人困惑......) – delnan 2010-12-16 20:02:22

0

正如有人说,这是失败的原因是,你哈希对象的字符串表示。我期望它交替的原因是因为字符串表示包含文件对象存储在的内存地址。当你这样做:

f = open(...) 

您存储文件对象f,指向内存X.当您再次做同样的事情,open()被调用,分配更多的内存。由于f仍然指向内存X,该内存仍在使用中,第二个open()改为在Y上分配新的内存。但是,只要open()返回结果分配给f。现在指向内存X的文件对象是悬空的并且被垃圾回收。 open()的下一个调用将在X处重用内存,因为它现在是免费的(这不是保证,但是很常见)

相关问题