如何逆向工程散列函数
我想创建一个函数,根据散列表中我希望值去的地方生成散列键。如何逆向工程散列函数
我的散列函数是(a + b * (key)) % c = hash value
。我见过一个similar question这对SO,和我的尝试与d
更换b * (key)
,只是这样做:
private int ReverseModulus(int a, int b, int c, int hashValue)
{
if(hashValue >= c)
return -1;
if(a < hashValue)
return (hashValue - a)/b;
return (c + hashValue - a)/b;
}
但似乎大部分时间hashValue != Hash(ReverseModulus(a,b,c, hashValue))
。
我想知道,如果做法是错误的,或者如果有只是在代码中的错误。
您正在使用错误的种类。你在做整数划分,但你需要做模块划分。在Java中,您可以使用BigInteger
:
bh = new BigInteger(hashValue);
ba = new BigInteger(a);
bc = new BigInteger(c);
bn = bh.subtract(ba);
return bn.modInverse(bc).intValue();
和C#推测具有类似的库函数。
不应该是'bn.multiply(bb.modInverse(bc))'?此外,您需要使用'BigInteger.valueOf()',而不是'new BigInteger()'。最后,乘数的倒数应该是一个常数,并且所有这些都是以'int'算法来计算效率:'return(h - a)* B_INV;' – erickson
@erickson我刚刚测试了您的建议,它的工作原理。只是好奇,B_INV是指什么? –
@Jedi_Maseter_Sam'B_INV'是'b'的乘法倒数,模'c'。我假设'c'是2^32,但如果不是,你只需要一个额外的操作,而不是依靠'int'算术溢出。如果你乘以'b'和'B_INV',模'c',你会得到1。你可以将'B_INV'计算为'BigInteger bb = BigInteger.valueOf(b),bc = BigInteger.valueOf(c); int B_INV = bb.modInverse(bc).intValue();'当你的程序启动时,或者相关的类被初始化时,或者甚至把它计算出来并写入你的程序中。那么你可以节省不必要的'BigInteger'开销。 – erickson
通过设计,哈希是单向的。 – Servy
我想你想读[完美散列函数(https://en.wikipedia.org/wiki/Perfect_hash_function) –
我知道有没有钥匙和哈希值之间的一个一对一的关系,但我只是想从无限数量的密钥中得到一个将产生所需散列值的密钥。例如,您可以通过从0开始迭代直到获得正确的散列值来蛮力。 –