Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中基于文件内容创建唯一密钥_Python_Hash_Cryptography_Checksum_Unique Key - Fatal编程技术网

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

在python中基于文件内容创建唯一密钥,python,hash,cryptography,checksum,unique-key,Python,Hash,Cryptography,Checksum,Unique Key,我有很多很多文件要上传到服务器上,我只想找到一种避免重复的方法 因此,从一个大字符串生成一个唯一的小键值似乎是校验和要做的事情,并且 所以我打算用hashmd5来做这个。但后来我读到“MD5不应该是唯一的键”,我觉得这真的很奇怪 正确的做法是什么? 编辑:顺便说一句,我开始了解以下内容,这就是我目前使用Python 2.5所做的工作,它工作得很好: import hashlib def md5_from_file (fileName, block_size=2**14): md5 =

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

因此,从一个大字符串生成一个唯一的小键值似乎是校验和要做的事情,并且

所以我打算用hashmd5来做这个。但后来我读到“MD5不应该是唯一的键”,我觉得这真的很奇怪

正确的做法是什么?

编辑:顺便说一句,我开始了解以下内容,这就是我目前使用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()

MD5的问题是它坏了。对于大多数常见的应用,这并没有什么问题,人们仍然使用MD5和SHA1,但我认为,如果您需要一个哈希函数,那么您就需要一个强哈希函数。据我所知,这两种方法都没有标准的替代品。有许多算法被认为是强大的,但我们对SHA1和MD5有着丰富的经验。也就是说,我们(认为)我们知道这两种算法何时崩溃,而我们并不知道新算法何时崩溃


一句话:考虑一下风险。如果您希望多走一英里,那么您可能会在发现散列重复时添加额外的检查,以换取性能损失。

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

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


诚然,使用2.6*10^18个条目的128位哈希值时,发生冲突的几率约为1%,但最好处理确实发生冲突的情况,而不是希望永远不会发生冲突。

坚持使用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并使用相同的方法。如果性能不是问题,甚至可以同时使用两者(连接)


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

在这种情况下,哈希函数的强度无关紧要。MD5将绝对防止复制到虚拟的数学确定性。什么是“散列函数的强度无关紧要”的意思?当前针对MD5的攻击允许您在一秒钟内在单个CPU上生成冲突——因此,不,MD5不会像其他地方所说的那样防止“重复”,MD5不会防止重复/冲突,尽管它确实使它们变得不太可能。此外,MD5只是在其加密不安全的意义上被“破坏”——如果需要的话,坚定的攻击者可以创建冲突。不过,出于最初问题的目的,加密安全是不必要的,因此这不是拒绝MD5的有效理由。生成固定长度哈希的哈希函数本质上容易发生冲突。只是我们不想找到两个散列为相同值的不同文本。我们知道碰撞就在那里,我们只是不想找到它们。更糟糕的是,当给定任意文本时,会出现一个问题,我们可以生成另一个对相同文本进行散列的不同文本;或者当给定一个散列时,我们可以生成一个散列到相同散列值的文本。这对OP来说有多严重只有OP知道:我认为这是一个风险评估的问题。好吧,我的案例实际上是关于大图像和大视频,性能是一个相当大的问题。但是,我并不期望它能检测出同一场景中两个稍有不同的角度。这绝对是最好的答案。但是,如果OP想要比SHA1更好,而不是串联,他应该只使用SHA2。在散列中添加更多数据只会更改散列函数(例如,这个答案说“在MD5返回的内容上附加一些其他值以生成更长的散列”)。有时这是最简单的,但您也可以首先生成更长的哈希。唉-更长的散列并不能防止冲突。#如何生成更长的散列?在关于hashlib的文档中,我看不到任何指向hashlib的内容。通过一个接一个地粘贴两个(独立)散列函数的结果,可以轻松地获得更长的散列。例如,如果您获取MD5返回值,然后将文件长度连接到MD5返回值上,那么您的散列会更长。文件长度不是一个好的哈希算法,但作为一个示例,它很有用。尽管我不知道任何公共哈希API,所以我不知道您将/可以为它们提供什么,尽管我怀疑MD5向后处理数据将产生足够不可重复的结果,将向前和向后哈希合并将是双倍的强度。使用“f=open(fileName,'rb')”要在Windows上获得正确的结果