我是加密/散列的初学者。我想知道如何散列一个可变长度的字符串,可能是10或100个字母到固定长度代码,例如128位二进制,无论底层编程语言如何,同时在二进制位之间实现相对相等的冲突。
具体来说,如何处理不同输入的输入,并使哈希码均匀分布?
答案 0 :(得分:1)
有很多不同的方法可以做到这一点。
对于非加密应用程序,通过迭代字符串序并应用一些操作将新字符的位与累积的哈希位混合来散列字符串是很常见的。关于你如何实现这一点的方式有很多变化。这里显示了一种常见的方法:
unsigned int kSmallPrime = /* some small prime */;
unsigned int kLargePrime = /* some large prime */;
unsigned int result = 0;
for (char ch: string) {
result = (result * kSmallPrime + ch) % kLargePrime;
}
更复杂的组合步骤可以获得更好的分布。这些方法通常不要求字符串具有任何特定长度并且适用于任何长度的字符串。你得到的比特数取决于你用来混合比特的内部存储量,虽然没有必要强烈的理论上的理由(除了经验证据)相信你有一个好的分布。
对于加密应用程序,字符串散列函数通常从分组密码派生。像Merkle-Damgard这样的结构允许您从安全块密码开始并生成安全散列函数。它们通过使用安全填充方案将字符串填充到块大小的某个倍数来工作(确保填充后不同的字符串最终不同),将字符串分成块,并在链中散列它们。最后的输出然后从底层块密码导出,它自然地输出大量的位,并且好的分布来自底层块密码的强度,(原则上)应该与随机无法区分。