Python 解哈希值

13 投票
4 回答
37104 浏览
提问于 2025-04-15 23:45

我刚接触Python,想问一下能不能把一个值“解哈希”,或者说怎么做才能解哈希。我现在在用标准的hash()函数。我想做的是先把一个值哈希处理,然后把它发送到某个地方,最后再把它解哈希,像这样:

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

谢谢大家!

4 个回答

7

你不能“还原”哈希数据,因为哈希函数是不可逆的,这跟鸽子洞原理有关。

http://en.wikipedia.org/wiki/Hash_function
http://en.wikipedia.org/wiki/Pigeonhole_principle

我觉得你想要的是加密和解密。(或者是压缩或者序列化,其他回答和评论中也提到过。)

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

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

关于不同基数和哈希长度的必要性,我就留给那些想深入了解哈希的人去研究了。

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或类似的安全加密算法
  • 序列化/反序列化,这是一种将复杂对象层次结构转换为二进制或文本表示的代码,之后可以再反序列化成新的对象

撰写回答