我有一个哈希解密功能。如果输入为664804774844
,则输出为agdpeew
。我使用modulo和division来查找字母索引。但是在while循环中我写了i = 7
因为我知道输出字符串(agdpeew
)的大小。我如何找到i
?
解密功能:
var f = function (h) {
var letters, result, i;
i = 7;
result = "";
letters = "acdegilmnoprstuw";
while (i) {
Result += letters [parseInt (h % 37)];
h = h / 37;
i--;
}
return result.split("").reverse().join("");
};
加密功能:
hash (s) {
h = 7;
letters = "acdegilmnoprstuw";
for(i = 0; i < s.length; i++) {
h = (h * 37 + letters.indexOf(s[i]));
}
return h;
}
答案 0 :(得分:1)
这取决于你如何处理溢出。如果你的“加密”功能允许输入的时间足够长,以至于h会在某个时刻溢出,那么你就会被填满,而你当前的解密方法根本不会起作用。
如果你可以保证没有溢出那么你的最后一个h将是表格的总和(An)x ^ n其中An是你的序列中的第n个字母通过你的indexof方法转换为数字(和x在这里案例是37)
你的解密基本上采用x ^ 0项(通过使用mod x),然后转换它。然后它除以x(大概使用整数数学)来丢失旧的x ^ 0项并得到一个新的解释。
这意味着你实际上可以继续这样做,直到你的h
为0,此时你知道你已经处理了所有的角色。
有趣的是,x只需要大于letters
的长度(因为An必须小于x)。较小的X会在溢出之前提供更多可能的输入字符。
如果您允许溢出,那么除非您知道输入有多长,否则您无法执行此操作。即使这样,它也可能很棘手。如果您的输入长度不受限制,那么您可以输入1000个字符,并且所有这些组合都有很多可能的h值。事实上事实并非如此。仍然有2 ^ 32个可能的结果(事实上你的算法更少),如果你有超过2 ^ 32个可能的输入,那么你不可能有一个可逆函数,因为你必须至少有2个输入才能匹配那个哈希值。
这就是为什么leppie说你无法解密哈希值,因为你在创建无法恢复的信息时会丢失信息。除非你有限制或其他信息,否则你就会陷入困境。