我有以下哈希算法:
unsigned long specialNum=0x4E67C6A7;
unsigned int ch;
char inputVal[]=" AAPB2GXG";
for(int i=0;i<strlen(inputVal);i++)
{
ch=inputVal[i];
ch=ch+(specialNum*32);
ch=ch+(specialNum/4);
specialNum=bitXor(specialNum,ch);
}
unsigned int outputVal=specialNum;
bitXor只执行Xor操作:
int bitXor(int a,int b)
{
return (a & ~b) | (~a & b);
}
现在我想找到一个算法,当给出outputVal时,它可以生成&#34; inputVal&#34; 。(生成的inputVal可能不一定与原始inputVal相同。这就是我想找到碰撞的原因。 这意味着我需要找到一种算法,该算法生成一个解决方案,当输入上述算法时,结果与指定的#34; outputVal&#34;相同。 要生成的解决方案的长度应小于或等于32 。
答案 0 :(得分:1)
方法1:蛮力。没什么大不了的,因为你的“specialNum”总是在一个int的范围内,所以在平均尝试几十亿个输入值之后,你找到了正确的输入值。应该在几秒钟内完成。
方法2:蛮力,但聪明。
在处理最后一个ch之前考虑specialNum值。你首先计算(specialNum * 32)+(specialNum / 4)+ ch。从-128&lt; = ch&lt; 128或0&lt; = ch&lt; 256取决于char的签名,你知道结果的最高23位,与ch无关。在使用specialNum xor'ing ch之后,您还知道最高的23位(如果ch是有符号的,则最高23位有两个可能的值)。检查这23位是否与所需输出匹配,如果不匹配,则一次性排除ch的所有256个值。所以蛮力方法将在1600万步之后平均结束。
现在考虑处理最后两个ch之前的specialNum值。同样,您可以确定结果的最高14位(如果ch用四个备选方案签名),而不检查最后两个字符。如果最高14位不匹配,则完成。
方法3:这是你如何做到的。反过来考虑所有长度为0,1,2等的字符串(但是,您的算法很可能会更快地找到解决方案)。处理字符串s后计算specialNum。根据您的算法,并允许对char进行签名,找到最多4个不同的值,即在处理另外两个字符后,specialNum的最高14位可能具有这些值。如果其中任何一个匹配所需的输出,则在处理下一个字符的256个可能值中的每一个之后检查specialNum的值,并在检查另一个char之后找到最多2个不同的值,即uniqueNum的最高23位。如果其中一个匹配所需输出的最高23位,那么在处理256个可能的下一个字符中的每一个并查找匹配后,检查specialNum将是什么。
这应该在毫秒以下工作。如果char未签名,则速度更快。