1:散列的主要目的是将一个非常非常大的空间映射到一个更小但仍然非常大的空间(例如,MD5,它将获取“任何东西”并将其转换为大小为 2^128 的空间 - 大,但没有 aleph-0 大。)
除了其他特性之外,好的散列可以均匀地填充目标空间。错误的散列以块状方式填充空间,为许多常见输入提供相同的散列。
想象一下愚蠢的哈希函数 sum(),它只是将输入数字的所有数字相加:它成功向下映射,但是在低位有一堆冲突(输入具有相同的输出,如 3 和 12 和 21)输出空间的末端和空间的上端几乎是空的。因此,它对空间的利用非常差,容易开裂等。
因此,即使使用目标空间的良好哈希将很难找到具有相同输出的两个输入,仅凭几率:如果 MD5 是完美的,两个输入具有相同输出的几率将是 2^- 128. 这是相当不错的几率:在不诉诸更大输出空间的情况下,您可以做到最好。(事实上 MD5 并不完美,这是使其易受攻击的原因之一。)
但是,大量的输入将映射到任何给定的哈希仍然是正确的,因为输入空间是“无限的”,并且将无穷大除以 2^128 仍然可以得到无穷大。
2:是的,哈希总是会导致数据丢失,除非您的输出空间与您的输入空间相同或大于输入空间 - 在这种情况下您可能不需要哈希!
3:对于较小的输入,最佳做法是对输入进行加盐。实际上,这对于任何加密散列都是一个很好的做法,因为否则攻击者可以向您提供特定的输入并试图找出您正在使用的散列。'Salt' 只是您在输入中附加(或前置)的一组附加信息;然后你散列结果。
编辑:在密码学中,哈希函数能够抵抗原像攻击也很重要,直观地说,即使知道许多其他输入/输出对,也很难猜测给定输出的输入。“sum”函数可能很容易被猜到(但由于它破坏数据仍然可能不容易反转)。