我写了一个用于密码和密钥生成的散列函数,但很快意识到能够反转散列是非常有价值的,所以我写了一个相反的函数,但是,它起作用了。我不知道为什么这个DOESNT会工作。
function hash64(n:uint):uint
{
n = (~n) + (n << 21);
n = n ^ (n >> 24);
n = (n + (n << 3)) + (n << 8);
n = n ^(n >> 14);
n = (n + (n << 2)) + (n << 4);
n = n ^ (n >> 28);
n = n + (n << 31);
return n;
}
function unhash64(n:uint):uint
{
n = (~n) - (n >> 21);
n = n ^ (n << 24);
n = (n - (n >> 3)) - (n >> 8);
n = n ^ (n << 14);
n = (n - (n >> 2)) - (n >> 4);
n = n ^ (n << 28);
n = n - (n >> 31);
return n;
}
喂1000时的输出:
Hashed from 1000: 1221775646
Unhash output: 1963490760
答案 0 :(得分:5)
第一个明显的问题是它没有及时镜像。 有时有效(如果操作顺序首先不重要),但通常y = f(g(x))
的倒数为x = g⁻¹(f⁻¹(y))
。 f最后应用,因此必须首先撤消。比较一下:如果你先穿上袜子然后穿上你的鞋子,你应该先脱掉鞋子然后脱掉袜子。
此外,许多反转开始时都是错误的。例如,相反的
m = n ^ (n >> 24)
为n = m ^ (m >> 24)
,而m = (n + (n << 2)) + (n << 4)
的倒数为n = m * 0x3cf3cf3d
(它是modular multiplicative inverse)。它并不像换班方向那么简单。
未经测试,但这些都是正确顺序的反转:
n = n * 0x80000001;
n = n ^ (n >> 28);
n = n * 0x3cf3cf3d;
n = n ^ (n >> 14) ^ (n >> 28);
n = n * 0x1c03dd39;
n = n ^ (n >> 24);
n = (n + 1) * 0xffdfffff;
答案 1 :(得分:1)
哈希不可逆转。如果您想要隐藏原始输入的可逆功能,请使用加密。只要您拥有正确的密钥,加密就是可逆的。
已经有众所周知的密码和密钥生成技术。如果您尝试设计自己的版本,那么它们将是不安全的。没关系,你要做的就是隐藏你孩子兄弟的东西。如果您在商业区工作,那么您可能会被起诉,因此请使用所有标准的现有安全方法。您可能想要研究关键衍生函数,如PBKDF2或argon2。