首页 > 解决方案 > 如何反转此自定义哈希

问题描述

所以我在 JS 中有这个散列算法,我想知道如何反转它产生的散列?我知道人们经常问这些问题,但这种散列算法是独一无二的(我认为)。这里是:

const stringToHash = string => { 
  var hash = 0; 

  if (string.length == 0) return hash; 

  for (i = 0; i < string.length; i++) {
    char = string.charCodeAt(i); 
    hash = ((hash << 5) - hash) + char; 
    hash = hash & hash; 
  } 

  return hash; 
}

这是它给我的示例输出:-566853151

标签: javascriptalgorithmhash

解决方案


对于已知非常短的消息(例如 4 个大写 ASCII 字符或更少),您的哈希很容易可逆

如果您的消息完全是大写或完全小写,则字符仅在 32 个块内不同,即 2^5。因此,当您将数字移动 5 位位置时,下一个输入字符不会重叠。

因此,您可以从最高位开始,读取第一个字符,然后考虑该字符将如何通过各个步骤(移位和减法)演变。这将允许您“撤消”第一个字符的效果。

您现在删除了第一个字符,剩余的哈希值更简单,即消息剩余字符的哈希值。然后您可以重复,直到完成所有字符。

如果消息较长,特别是如果允许包含更广泛的符号数组,那么您的任务就会困难得多。

让我知道这是否有助于您入门:

const stringToHash = string => { 
  var hash = 0; 

  if (string.length == 0) return hash; 

  for (i = 0; i < string.length; i++) {
    char = string.charCodeAt(i); 
    hash = ((hash << 5) - hash) + char; 
    hash = hash & hash; 
  } 

  return hash; 
}

console.log(stringToHash("A").toString(2))
console.log(stringToHash("AA").toString(2))
console.log(stringToHash("AAA").toString(2))

console.log(stringToHash("B").toString(2))
console.log(stringToHash("BA").toString(2))
console.log(stringToHash("BAA").toString(2))


推荐阅读