Python 解哈希值
我刚接触Python,想问一下能不能把一个值“解哈希”,或者说怎么做才能解哈希。我现在在用标准的hash()函数。我想做的是先把一个值哈希处理,然后把它发送到某个地方,最后再把它解哈希,像这样:
#process X
hashedVal = hash(someVal)
#send n receive in process Y
someVal = unhash(hashedVal)
#for example print it
print someVal
谢谢大家!
4 个回答
你不能“还原”哈希数据,因为哈希函数是不可逆的,这跟鸽子洞原理有关。
http://en.wikipedia.org/wiki/Hash_function
http://en.wikipedia.org/wiki/Pigeonhole_principle
我觉得你想要的是加密和解密。(或者是压缩或者序列化,其他回答和评论中也提到过。)
即使我现在回答这个问题已经晚了快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
你可以在初始化哈希函数时定义哈希长度,并且可以哈希其他数据类型。
关于不同基数和哈希长度的必要性,我就留给那些想深入了解哈希的人去研究了。
这件事是做不到的。
哈希并不是原始值的压缩版本,而是从原始值“派生”出来的一个数字(或者类似的东西)。哈希的实现方式使得虽然可能性不大(如果哈希算法设计得好),但两个不同的对象可能会产生相同的哈希值。
这就是所谓的鸽巢原理,简单来说就是如果你有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或类似的安全加密算法
- 序列化/反序列化,这是一种将复杂对象层次结构转换为二进制或文本表示的代码,之后可以再反序列化成新的对象