31位双射(完美)哈希算法

时间:2019-05-02 17:59:01

标签: algorithm hash crc perfect-hash bijection

我需要的

我需要一种产生双射输出的算法。我有一个31位输入,需要一个伪随机的31位输出。

我考虑过的

CRC在其位宽内是双射的。

我看过Google,可以找到多项式,但是找不到表或算法。

有人能指出我正确的方向吗?

我需要使用多项式(例如0x737e312b)的CRC-31算法,或者可以满足我需要的任何双射函数。

注意

我找到了以下代码,但是很遗憾,我没有编译和运行它的工具。

1 个答案:

答案 0 :(得分:3)

对于任何哈希函数hash,您可以执行以下操作:

function bijectiveHash31(int val) {
    val &= 0x7FFFFFFF; //make sure it's 31 bits
    for (int i=0; i<5; ++i) {
        // the high bits affect the low bits
        val ^= hash(val>>15) & 32767;
        // rotate bits
        val = ((val&32767)<<16) | ((val>>15)&65535);
    }
    return val;
}

这是一个Feistel结构,它构成许多密码的基础:https://en.wikipedia.org/wiki/Feistel_cipher

如果您需要它快速但又不需要超级好,那么效果很好:

function bijectiveHash31(int val) {
    val = ((val*RANDOM_ODD_NUMBER) + RANDOM_NUMBER) & 0x7FFFFFFF;
    val ^= (val>>15);
    val ^= (val>>8);
    return val;
}

在这两种情况下,弄清楚如何撤消每个基本操作也不难,这表明整个哈希是双射的。如果需要帮助建立乘法,请参阅https://en.wikipedia.org/wiki/Modular_multiplicative_inverse