Python无法哈希值的解决方法

13

我是 Python 的新手。我能够取消哈希值吗?或者更确切地说,我如何取消哈希值?我正在使用标准的 hash() 函数。我的目标是首先哈希一个值,将其发送到某个地方,然后再取消哈希:

#process X
hashedVal = hash(someVal)
#send n receive in process Y
someVal = unhash(hashedVal)
#for example print it
print someVal

提前感谢


你是在谈论序列化吗? - SilentGhost
3
你为什么想这样做?你是想通过只发送哈希值并在另一端解密来加快发送3GB数据的速度吗?这种方法行不通... - Mark Byers
如果这种方法可行,许多神秘的系统将会被淘汰。 - xiao 啸
嘿,Google的标志几乎是用彩虹颜色制作的,你可以使用它! :) - mykhal
4个回答

31

无法完成。

哈希不是原始值的压缩版本,它是从原始值派生出来的数字(或类似物)。哈希实现的本质是可能的(但如果哈希算法是好的,则在统计上不太可能)两个不同的对象产生相同的哈希值。

这被称为鸽巢原理,基本上是指如果你有N个不同的项目,并想将它们放入M个不同的类别中,其中N的数量大于M(即更多的项目而不是类别),你最终将得到一些包含多个项目的类别。由于哈希值通常比其哈希数据小得多,因此遵循相同的原则。

因此,一旦你拥有哈希值,就无法回溯。您需要一种不同的传输数据的方式。

例如,一个示例(但不是非常好的)哈希算法是计算数字模3(即除以3后的余数)。然后,您将从数字获得以下哈希值:

1 --> 1  <--+- same hash number, but different original values
2 --> 2     |
3 --> 0     |
4 --> 1  <--+

你是想这样使用哈希函数,以便于:

  • 节省空间(你已经观察到哈希值的大小比原始数据小得多)
  • 保证传输安全(你已经观察到哈希值很难被反向破解)
  • 传输数据(你已经观察到哈希数字/字符串比复杂对象层次结构更易于传输)

...吗?

了解你为什么要这样做可能会给你一个比“它无法完成”更好的答案。

例如,针对以上三种不同的观察方式,以下是每种方式正确的实现方法:

  • 压缩/解压缩,例如使用gzip或zlib(这两种通常在大多数编程语言/运行时中都可用)
  • 加密/解密,例如使用RSA、AES或类似的安全加密算法
  • 序列化/反序列化,这是一种代码,用于将复杂的对象层次结构转换为二进制或文本表示形式,稍后可以将其反序列化回新对象中

在Python中,__hash__方法与您创建的任何哈希表无关。假设您有一个名为tabby的哈希表。那么hash(“hello world”)与某个数字x%len(tabby)不同。当您对字符串进行哈希,或对元组进行哈希,或在Python中对任何内容进行哈希时,所得到的数字与用户创建的哈希表中条目数量无关。 - Samuel Muldoon
有很多Python库基于__hash__()定义了==运算符(或__eq__())。例如,我们可以让"hello" == "world"仅在hash("hello") == hash("world")时返回True。如果str类的每个实例的哈希值都是唯一的,那么理论上可以将它们解密。 - Samuel Muldoon

18
即使我晚了将近8年才回答,我想说解密数据是可能的(尽管不能使用标准的hash()函数)。
之前的答案都在描述加密哈希函数,这种哈希函数的设计应该计算出不可能(或至少非常难)被解密的哈希值。
然而,并非所有哈希函数都是如此。
解决方法:
您可以使用basehash Python库(pip install basehash)来实现所需功能。
但需要记住一件重要的事情:为了能够解密数据,您需要保证没有数据丢失的情况下进行哈希。通常这意味着,您希望哈希类型和值的数据池越大,哈希长度就需要越大,以便避免哈希冲突。
无论如何,以下是一个简单的示例,演示如何哈希/解密数据:
import basehash

hash_fn = basehash.base36()  # you can initialize a 36, 52, 56, 58, 62 and 94 base fn
hash_value = hash_fn.hash(1) # returns 'M8YZRZ'
unhashed = hash_fn.unhash('M8YZRZ') # returns 1

你可以在哈希函数初始化时定义哈希长度并哈希其他数据类型。

我不会解释各种基数和哈希长度的必要性,对于想要了解更多关于哈希的读者,请自行查找。


7

或者压缩/解压缩。 - Felix Kling

0
一般情况下这是不可能的。哈希函数必然会丢失信息,Python 的 hash 也不例外。

在Python中,有很多类基于__hash__()定义了operator ==(或__eq__())。例如,我们可以使得"hello" == "world"仅当hash("hello") == hash("world")时返回True。如果每个字符串的哈希值是唯一的,那么理论上就有可能将它们解密。 - Samuel Muldoon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接