代码之家  ›  专栏  ›  技术社区  ›  cregox

基于python中的文件内容创建唯一密钥

  •  4
  • cregox  · 技术社区  · 15 年前

    我有很多很多文件要上传到服务器,我只想找到一种避免重复的方法。

    因此,从一个大字符串生成一个唯一的小键值似乎是校验和要做的事情,以及 hashing seemed like the evolution of that .

    所以我打算用hash md5来做这个。但后来我读了 somewhere “MD5不是唯一的钥匙”,我觉得这很奇怪。

    正确的方法是什么?

    编辑: 顺便说一下,我 two sources 要了解以下内容,这就是我目前的工作方式,而且它在使用python 2.5时工作得很好:

    import hashlib
    
    def md5_from_file (fileName, block_size=2**14):
        md5 = hashlib.md5()
        f = open(fileName)
        while True:
            data = f.read(block_size)
            if not data:
                break
            md5.update(data)
        f.close()
        return md5.hexdigest()
    
    4 回复  |  直到 15 年前
        1
  •  5
  •   Jj.    15 年前

    坚持MD5是个好主意。只是为了确保将文件长度或块数附加到文件哈希表中。

    是的,有可能会遇到两个具有相同MD5哈希的文件,但这不太可能(如果文件大小合适)。因此,向哈希中添加块的数量可能有助于减少这种情况,因为现在您必须找到两个大小相同、MD5相同的文件。

    # This is the algorithm you described, but also returns the number of chunks.
    new_file_hash, nchunks = hash_for_tile(new_file)
    store_file(new_file, nchunks, hash)
    
    def store_file(file, nchunks, hash):
      "" Tells you whether there is another file with the same contents already, by 
         making a table lookup ""
      # This can be a DB lookup or some way to obtain your hash map
      big_table = ObtainTable()
    
      # Two level lookup table might help performance
      # Will vary on the number of entries and nature of big_table
      if nchunks in big_table:
         if hash in big_table[hash]:
           raise DuplicateFileException,\
             'File is dup with %s' big_table[nchunks][lookup_hash]
      else:
        big_table[nchunks] = {}
    
      big_table[nchunks].update({
        hash: file.filename
      })
    
      file.save() # or something
    

    为了减少这种可能性,切换到sha1并使用相同的方法。如果性能不是问题,甚至可以同时使用(连接)。

    当然,请记住,这只适用于二进制级别的重复文件,而不适用于“相同”但具有不同签名的图像、声音和视频。

        2
  •  3
  •   dash-tom-bang    15 年前

    散列的问题是,它正在从“大”数据集生成一个“小”标识符。就像有损压缩。虽然您不能保证唯一性,但您可以使用它来大幅限制需要比较的其他项目的数量。

    假设MD5产生一个128位的值(我认为这就是它,尽管确切的位数是不相关的)。如果您的输入数据集有129位,并且您实际使用了所有这些位,那么每个MD5值将平均显示两次。对于更长的数据集(例如“所有1024个可打印字符的文本文件”),一旦获得足够的输入,您仍然会遇到冲突。与另一个答案所说的相反,在数学上你肯定会遇到碰撞。

    http://en.wikipedia.org/wiki/Birthday_Paradox

    当然,在2.6*10^18个条目中,与128位哈希冲突的概率大约为1%,但是最好处理发生冲突的情况,而不是希望永远不会发生冲突。

        3
  •  2
  •   wilhelmtell    15 年前

    MD5的问题是它坏了。对于最常见的用法,几乎没有问题,人们仍然使用MD5和SHA1,但是我认为如果您需要哈希函数,那么您需要一个强大的哈希函数。据我所知,目前还没有标准的替代品。有许多算法“应该”很强大,但我们在sha1和md5方面拥有最多的经验。也就是说,我们(认为)知道这两种算法何时中断,而实际上我们不太知道新算法何时中断。

    底线:考虑风险。如果你想多走一英里,那么你可以在找到一个哈希副本时添加额外的检查,作为性能惩罚的代价。

        4
  •  0
  •   kenm    15 年前

    提示:想想哈希表是如何工作的。