单向散列(无冲突)将32位整数转换为36位整数?

时间:2012-07-24 05:55:08

标签: algorithm hash cryptography

我想使用单向散列算法(无冲突)将32位整数转换为36位整数。

任何人都可以解释如何做到这一点吗?

2 个答案:

答案 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. 生成一个包含4,294,967,296个随机36位数字的列表,在每个条目中添加一个32位数字,即条目行号(从0开始)。
  2. 对列表进行排序。
  3. 重置did-change-a-number-flag
  4. 浏览列表。将实际条目与前一个条目进行比较。如果它们不同,请转到步骤7.
  5. 将36位数字替换为新的随机36位数字
  6. 设置did-change-a-number-flag
  7. 如果到达列表的末尾:是否设置了标志?如果是,请转到步骤2.
  8. 按32位数(前一行号)
  9. 对列表进行排序

    在第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位输入,谁在乎呢?)