反转字符串哈希函数

时间:2020-03-24 09:11:15

标签: c# hash reverse

我具有以下功能,这些功能 string

public static uint hashString(string myString)
{
     uint hash = 0;

     foreach (char c in myString)
     {
         hash *= 0x1F;
         hash += c;
     }

     return hash;
}

因此,如果我想对hello进行哈希处理,它将产生99162322

是否可以编写 reverse 函数,该函数接受number并吐出string(假设string result < / em>是未知)?

2 个答案:

答案 0 :(得分:3)

由于您不使用 cryptographic 哈希,因此您的实现很容易 reverse (即返回 some string给定的哈希值)

代码:

public static uint hashString(string myString) {
  //DONE: validate public methods' parameters
  if (null == myString)
    return 0;

  uint hash = 0;

  //DONE: hash function must never throw exceptions
  unchecked {
    foreach (char c in myString) {
      hash *= 0x1F;
      hash += c;
    }
  }

  return hash;
}

private static string HashReverse(uint value) {
  StringBuilder sb = new StringBuilder();

  for (; value > 0; value /= 31) 
    sb.Append((char)(value % 31));

  return string.Concat(sb.ToString().Reverse());
}

演示 :(给定hash,我们产生了string并从中计算出hash进行检查)

uint[] tests = new uint[] {
  99162322,
  123,
  456
};

// Since the string can contain control characters, let's provide its Dump
string Dump(string value) => string.Join(" ", value.Select(c =>((int) c).ToString("x4")));

string report = string.Join(Environment.NewLine, tests
  .Select(test => new { 
    test,
    reversed = HashReverse(test)
  })
  .Select(item => $"{item.test,9} :: {Dump(item.reversed),-30} :: {hashString(item.reversed),9}"));

Console.WriteLine(report);

结果:

 99162322 :: 0003 000e 000b 0012 0012 0012  ::  99162322
      123 :: 0003 001e                      ::       123
      456 :: 000e 0016                      ::       456

请注意,很多一个string会产生相同哈希值(例如"hello"和我的"\u0003\u000e\u000b\u0012\u0012\u0012"

答案 1 :(得分:1)

否。

散列的基本要点之一是它是不可逆的。

有许多字符串会产生具有99162322的字符串,因此虽然有可能找到所有字符串(给定最大字符串长度),但无法确定哪个是“正确的”。