在Python中生成唯一哈希的最安全方法

zzwlnbp8  于 2024-01-05  发布在  Python
关注(0)|答案(3)|浏览(185)

我需要生成唯一的标识符,这些标识符可以用于文件名,并且可以在给定相同的输入值时复制。我需要生成数百万个这些标识符,因为源输入有数百万个组合。
为了简单起见,我将在示例中使用一个小的集合,但实际的集合可以相当大(数百个,也许数千个项目);比手动编码到文件名中的要大。
我注意到生成UUID的第五种方法允许您提供字符串输入。

  1. > input_set = {'apple', 'banana', 'orange'}
  2. > uuid.uuid5(uuid.NAMESPACE_URL, pickle.dumps(input_set)).hex
  3. 'f39926529ad45997984643816c1bc403'

字符串
文档中说它使用了SHA1。冲突的风险是否太高?是否有更好的方法来可靠地散列唯一标识符?

yhived7q

yhived7q1#

字符串发生SHA1冲突的几率非常低,目前已知的SHA1冲突不到63个。
First ever SHA1 collision found
第一次SHA-1哈希冲突计算。所有这一切都需要五个聪明的大脑......和6,610年的处理器时间
SHA1在密码学世界中不再被认为是安全的,但肯定超出了您的期望。
加密散列函数被设计为one way functions。这意味着函数的逆是“很难”计算的。(即知道输出对确定输入没有任何帮助)正如Blender在评论中指出的那样,这与碰撞的可能性无关。
查看Birthday Paradox,了解有关如何计算冲突概率的一些基本信息。
This question解决了SHA1冲突的可能性。
一个密码散列函数具有可证明的安全性,如果发现冲突是可证明的多项式时间可约化的,而问题P在多项式时间内是不可解的,那么这个函数就称为可证明安全的,或者仅仅是可证明的。
Here是一个“安全”哈希算法列表。

UPDATE您在评论中指出您的输入远远大于SHA1的160位限制。我建议您在这种情况下使用SHA 3,因为您的输入大小没有限制。查看Python documentation以了解更多信息。

下面是一个基本的例子:

  1. import sha3
  2. k = sha3.keccak_512()
  3. k.update(b"data")
  4. k.hexdigest()
  5. '1065aceeded3a5e4412e2187e919bffeadf815f5bd73d37fe00d384fe29f55f08462fdabe1007b993ce5b8119630e7db93101d9425d6e352e22ffe3dcb56b825'

字符串

展开查看全部
l2osamch

l2osamch2#

除了使用pysha3(参见DoesData的答案),您还可以使用内置模块hashlib

  1. import hashlib
  2. h = hashlib.sha3_512() # Python 3.6+
  3. h.update(b"Hello World")
  4. h.hexdigest()

字符串
输出量:

  1. '3d58a719c6866b0214f96b0a67b37e51a91e233ce0be126a08f35fdf4c043c6126f40139bfbc338d44eb2a03de9f7bb8eff0ac260b3629811e389a5fbee8a894'

vxf3dgd4

vxf3dgd43#

如果较小的base64.urlsafe_b64encode输出更可取:

  1. > import base64, hashlib
  2. > base64.urlsafe_b64encode(hashlib.sha3_512('asdf'.encode()).digest())
  3. b'jYjPWyD1Os164UebWzbcICF1OwSZAsdyR7snsTGzAL08qL7vKHVtzie4mQhnxFd6JTXn47dRQTmcoalMyEsOuQ=='

字符串
上述输出的长度为88,而相应的十六进制的长度为128。

相关问题