【问题标题】:alternate different shas of the same file. why?交替使用同一文件的不同 sha。为什么?
【发布时间】:2010-12-17 04:09:48
【问题描述】:

谁能给我一个为什么我得到同一个文件的备用 shas 的原因?但是每秒都一样吗?

>>> 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'

【问题讨论】:

    标签: python sha


    【解决方案1】:

    您得到不同哈希值的原因是因为您并没有真正对文件的内容进行哈希处理,而只是对文件对象的字符串表示进行了哈希处理。例如:

    >>> 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
    

    【讨论】:

    • @katrielalex:是的,刚刚添加了它。谢谢
    【解决方案2】:

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

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

    不过,我不确定为什么会这样。

    【讨论】:

    • 嗯,如果0xb7855230 是一个地址,那么如果str(f) 每次都读入不同的地址,那么它可能会有所不同,那么sha 会有所不同?
    • open 函数求值,创建一个新文件。它存储在f。如果覆盖f,则先前指向的f 将被破坏,从而释放特定内存位置的空间。该位置是打开文件所需的确切大小,因此下次调用 open 时会使用它。
    • +1 至于为什么它会交替出现:可能是因为 CPython 堆管理的讨厌的内部结构。 (Python 3 使用不同的 repr,不包括 id - 每次都给出相同的 str;非常混乱......)
    【解决方案3】:

    正如其他人所说,失败的原因是您正在散列对象的字符串表示形式。我希望它交替的原因是因为字符串表示包括文件对象存储的内存地址。当你这样做时:

    f = open(...)
    

    您将该文件对象存储在f 中,指向内存X。当您再次执行相同操作时,将调用open() 并分配更多内存。由于f 仍然指向内存X,因此该内存仍在使用中,而第二个open() 在Y 处分配新内存。但是,只要open() 返回,结果就会分配给f。现在指向内存 X 的文件对象悬空并被垃圾收集。下一次调用 open() 将重用 X 处的内存,因为它现在是免费的(这不能保证,但很常见)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      • 2012-06-07
      • 2018-08-06
      相关资源
      最近更新 更多