【问题标题】:How to reverse engineer hash function如何对哈希函数进行逆向工程
【发布时间】:2017-07-11 16:41:09
【问题描述】:

我正在尝试创建一个函数,该函数根据我希望值在哈希表中的位置生成哈希键。

我的哈希函数是(a + b * (key) ) % c = hash value。我在 SO 上看到了 similar question,我尝试用 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))

我想知道这种方法是错误的还是只是代码中的错误。

【问题讨论】:

  • 哈希在设计上是一种方式。
  • 我想你想看Perfect Hash Function
  • 我知道键和哈希值之间没有一对一的关系,但我只想从产生所需哈希值的无数键中获取一个。例如,您可以通过从 0 开始迭代直到获得正确的哈希值来强制它。
  • @Servy 好吧,只要您将线性同余生成器称为哈希......
  • @Servy 不正确。有很多可逆的哈希值。哈希必须专门设计为一种方式。

标签: java c# math hash


【解决方案1】:

您使用了错误的除法。你正在做整数除法,但你需要做模除法。在 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 我刚刚测试了您的建议并且它有效。只是好奇,B_INV 指的是什么?
  • @Jedi_Maseter_Sam B_INVb 的乘法逆,以 c 为模。我假设 c 是 2^32,但如果不是,您只需要一个额外的操作,而不是依赖 int 算术溢出。如果将bB_INV 相乘,以c 为模,则得到1。您可以将B_INV 计算为BigInteger bb = BigInteger.valueOf(b), bc = BigInteger.valueOf(c); int B_INV = bb.modInverse(bc).intValue(); 在程序启动或相关类初始化时执行此操作,甚至将其计算出来并将其写入程序中。这样你就可以节省不必要的BigInteger 费用。
猜你喜欢
  • 2014-05-16
  • 2018-08-26
  • 2017-02-15
  • 2016-09-28
  • 2014-02-22
  • 2011-05-09
  • 2011-05-15
  • 2016-04-01
相关资源
最近更新 更多