我想使用单向散列算法(无冲突)将32位整数转换为36位整数。
任何人都可以解释如何做到这一点吗?
答案 0 :(得分:8)
“单向”意味着,很难弄清楚x给出的哈希结果h(x)是什么。由于术语“硬”没有明确定义,因此对于单向函数也没有明确的定义。
“无碰撞”意味着对于每对x和y,h(x)不同于h(y),其中x与y不同。这是一个明确的定义,但很难证明h(x)是否是一个单向函数。您必须比较每对两个32位数的哈希结果,并测试它们是否不同。
执行此操作的最佳方法是计算所有可能的h(x)并将它们与x一起存储在数组中。然后用h(x)对数组进行排序,然后遍历此列表并测试两个邻居是否具有相同的h(x)。如果找不到相同的邻居,则哈希函数不会发生冲突。
但是:如果你真的可以做到这一点,你的功能实际上不是一个单向函数,因为你刚刚生成的用于证明无碰撞的列表是一个非常快速的查找 - 允许您在log(n)的搜索时间中找到每个h(x)的x的表。这甚至可能比从x计算h(x)更快。
让我们弄清楚,实际需要多长时间
32位整数是介于0和4294967295之间的数字。假设从x计算h(x)需要0.1 ms。根据哈希算法,即使在便宜的笔记本电脑上也是如此。因此,在1秒钟内,您将获得10,000个哈希数字,并在一天内获得864,000,000个数字。只需5天就可以计算所有可能的数字并将它们存储在光盘上。
每个条目对于32位数字具有4个字节,对于36位散列具有5个字节。制作9个字节。所以完整的表有38,654,705,664字节。这是38 GB。您可以将其存储在每个低限度笔记本电脑上。对此表进行排序需要几分钟,这不计算我们计算所需的5天。
所以建立这张桌子200 $ -notebook绝对没问题。一旦你拥有它,很容易证明它是否真的无碰撞,但通过构建这个表你也证明它不是单向函数!
那么什么是最佳解决方案?
在第1步之后,该列表将包含6,25%的碰撞(大约2.684亿次碰撞)。在每次迭代中,您将冲突数量减少到其第16个部分。它将花费大约8次迭代来消除所有的碰撞。
这38 GB表现在是超快速绝对无冲突的哈希函数。并且它是单向的,因为任何32到36位的散列函数都可以。含义:没有其他无冲突的哈希函数,在给定的h(x)中找到x更难。
答案 1 :(得分:3)
如果38 GB对你来说听起来不小,你可以使用带有36位块的Luby-Rackoff construction。
首先,根据需要将32位输入填充为36位。
然后生成一堆独立的随机密钥Ki
。让它们尽可能大。比如80比特。将这些Ki
存放在安全的地方,因为每次“哈希”时都会使用它们。
对于舍入函数F(Ki,x)
,请将SHA1(Ki . x)
截断为18位。
四轮这应该做得很好。它肯定是一对一的,因为如果你有Ki
,它实际上是可逆的。
(是的,“从不发明自己的密码术。”但只有32位输入,谁在乎呢?)