是否有可能解密Peter Weinberger的Hash算法?
我正在尝试编写自己的Encrypt Decrypt函数。我理解哈希值意味着你不能或不应该解密哈希值的概念,但我认为因为算法相对简单,在这种情况下可能解密这种哈希。我已经完成了使用简单旋转的简单加密解密,现在我想尝试更困难的事情。
那么可以解密Peter Weinberger的哈希算法产生的哈希值吗?
以下加密函数是Peter Weinberger的精确哈希算法,解密是我自己的尝试,但不起作用:
int encrypt(char *s)
{
/* Peter Weinberger's */
char *p;
unsigned int h, g;
h = 0;
for(p=s; *p!='\0'; p++){
h = (h<<4) + *p; printf("Step : ");
if (g = h&0xF0000000) {
h ^= g>>24;
h ^= g;
}
}
return h % 211;
}
std::string decrypt(int v)
{
/* Peter Weinberger's */
unsigned int h, g;
h = 0;
v /= 211;
int s = sqrt(v);
/* Not sure what to do here
for(p=s; *p!='\0'; p++){
}
*/
return string(h);
}
答案 0 :(得分:3)
考虑到极小的输出尺寸,蛮力攻击是微不足道的。
这将平均需要211次尝试才能获得与给定哈希匹配的字符串。它可能不会是原始字符串,但考虑到散列的有损性质,这是可以预期的。
对于两个字符输入,此哈希变为(16*s[0]+s[1])%211
,您可以将其重写为(16*(s[0]-'A')+(s[1]-'A') + 50)%211
解决你得到的字符串:
s[0]=(hash+161)/16+'A';
s[1]=(hash+161)%16+'A';
例如,对于s == "AB"
,您获得hash==51
。然后使用上面的公式来反转它:
s[0] = 13 +'A' = 'N'
s[1] = 4 +'A' = 'E'
=&GT; s="NE"
与哈希51匹配,但不是原始字符串。
答案 1 :(得分:0)
如果我正确理解算法,则对每个字符都这样做:
通过将字符串限制为大小为6(如果第一个字节小于16,则为7),将永远不会发生步骤3。所以剩下的就是一个简单的移位和添加。
当字符串有6个字符时,最终结果是这个总和(h =字符的高4位,l =低4位):
pos: bits
0: .hl00000
1: ..hl0000
2: ...hl000
3: ....hl00
4: .....hl0
5: ......hl
----------- +
0******* Result is 32 bits with upper 4 bits zero
我们看到位24-27由位置0处字符的高4位确定,加上低位中加法的可能进位。第20-23位是char 0的低位和char 1的高位(加上可能的进位)的总和。
如果输入字符可以包含所有255个可能值(零除外),则创建生成哈希值的字符串并不难。
代码会更复杂,因为存在各种边缘情况(例如散列01000000),并且留给读者作为练习;)。
编辑:我完全错过了h % 211
操作。这使得它变得更加容易,正如CodesInChaos演示的那样。