我们正在努力解决我们的开发团队内部的争论:
我们正在寻找一个64位的PHP哈希函数。 我们发现一MurmurHash3的PHP实现 ,但MurmurHash3是32位或128位,而不是64位。
同事#1认为,以从MurmurHash3 64位的哈希值,我们可以简单的切片128位散列的第一个(或最后一个,或任何)64位,它会随着碰撞的证明作为本地64位的散列函数。
同事#2认为,我们必须找到一个纯64位的散列函数,以减少碰撞和一个128位散列的64位片也不会碰撞的证明作为本机的64位散列。
谁是正确的?
其答案是否变化,如果我们采取像SHA1代替Murmur3密码散列的第一(或最后,或任何)64位?
如果你有真正的随机,均匀分布的值,然后在“切片”究竟会产生相同的结果,如果你用了,从一开始的较小值开始。 要知道为什么,考虑这个非常简单的例子:假设你的随机数发生器输出3个随机位,但你只需要一个随机位的工作。 假设输出
b1 b2 b3
可能的值是
000, 001, 010, 011, 100, 101, 110, 111
而且都以相同的概率为1/8发生。 现在,来自这三个你的目的切片无论位 - 第一,第二或第三 - 有一个“1”的概率总是将是1/2,而不管位置 - 而同样是“0真”。
您可以轻松地扩展这个实验到64出的128位情况:无论哪个位你切,与一个或某一位置上的零结束了的概率将是一个一半。 这意味着, 如果你有从一个均匀分布的随机变量采集的样品,然后切片就不会使概率碰撞或多或少可能。
现在一个很好的问题是随机的功能是否真的可以做,以防止冲突的最好的。 但事实证明,它可以证明,发现冲突的概率增加了,每当一个函数从随机偏离。
加密散列函数:同事#1胜
在现实生活中的问题是,哈希函数不是随机可言,相反,他们是乏味确定性。 但是,加密散列函数的设计目标是:如果我们不知道它们的初始状态,那么它们的输出是从一个真正的随机函数计算别无二致,即没有计算有效的方式来告诉散列输出之间的差别和真正的随机值。 这就是为什么你会考虑散列已经作为一种打破,如果你能找到一个“识别器”,一个方法来分辨真正的随机值的哈希以超过一半以上的概率。 不幸的是,我们确实不能证明这些特性对现有加密哈希,但除非有人破坏他们,我们可以假设这些性质有信心持有。 下面是一个的例子纸有关示出的过程中SHA-提交3中的一个的识别器。
总之,除非区分器发现对于给定的密码散列,切片是完全正常的,并不会增加冲突的可能性。
非加密散列函数:同事#2要得
非加密散列不必满足同一组的要求,加密散列做。 他们通常被定义为是非常快的,并且满足一定性能的“理智/仁慈的情况下”,但他们可能很容易功亏一篑,如果有人试图恶意操纵它们。 什么这意味着在实践中一个很好的例子是在哈希表的实现(计算复杂度攻击hashDoS今年早些时候提交)。 在正常情况下,非加密散列完全正常工作,但是它们的抗冲突性可以通过一些巧妙的输入受到严重损害。 这不能与加密散列函数发生,因为他们本身的定义要求它们不受各种巧妙的投入。
因为它是可能的,有时甚至是很容易,要找到像上面的非加密散列的输出了一个标识符,马上就可以说他们没有资格作为加密散列函数。 能够看出其中的差别意味着某处有输出图案或偏见。
而这一事实本身意味着他们更偏离或随机函数小,因而(在我们上面说的)冲突可能是更有可能比他们将是随机函数。 最后,由于碰撞具有较高的发生概率为全128位已经,这不会得到较短ouptputs更好,冲突可能会更加容易在这种情况下。
TL;博士截断当你和一个加密散列函数的安全。 但你比起截断非加密哈希有较大的输出为64位是一个“原生”的64位加密散列函数更好。
由于雪崩效应,强大的散列是其中在源结果变化在平均散列翻转的一半的位的单个位。 对于良好的散列,然后,将“hashness”是均匀分布的,所以每个部分或切片被相等且均匀地分布量源位的影响,并且因此仅仅是作为相同的比特长度的任何其它片段为强能是。
我想,只要有同事1达成协议散具有良好的性能和均匀分布。
这个问题似乎不完整这个被提及:
一些哈希值是可证明完美特定类的输入散列(例如,用于长度的输入n
对于一些合理值n
)。 如果截断散列,那么你很可能会破坏该财产,在这种情况下,你是根据定义,从零增加碰撞的速度为非零和你已经削弱了该用例的哈希值。
这不是一般的情况,但截断散列当它是一个正当关切的一个例子。
文章来源: Is any 64-bit portion of a 128-bit hash as collision-proof as a 64-bit hash?