A^((A >> 2) + (A << 5) + C) == B
如何查找A如果B是常量而C是變量?顛倒散列,查找衝突(與總和和左/右位移異或)
A爲DWORD(C可如果它沒有辦法來改變),B爲DWORD,C是字節= 0
EDIT1:GalacticJello的回答後,我收到了另一個問題:有沒有辦法做到沒有循環(簡化表達式)?
爲什麼我需要這樣的: 我試圖做一個反向功能(碰撞搜索)爲
unsigned int X(const char* const in) { //strlen(in) is always < 127
unsigned int result = 0x12345678; //just for an example
for(int i = 0; in[i] != 0; ++i)
result ^= (result >> 2) + (result << 5) + in[i];
return result;
}
目前我有一個生成隨機C,然後循環搜索A. (我搜索一個使用產生的隨機值[對於A],並檢查是否上述表達式爲真環路)
EDIT2:這是我的當前搜索的碰撞,即我現在測試代碼..
#include <stdio.h>
#include <conio.h>
using namespace std;
unsigned int originalHash(const char* const in) {
unsigned int result = 0x12345678;
for(int i = 0; in[i] != 0; ++i) {
result = result^((result >> 2) + (result << 5) + in[i]);
}
return result;
}
//A^((A >> 2) + (A << 5) + C) == B
bool findSolutions(unsigned int inHash, char* _C, unsigned int* _A) { //Starts searching from *A and *C and writes there values on success.
unsigned int C = *_C;
if(C == 0) ++C;
unsigned int A = *_A;
for(C; C < 256; ++C) {
for(A; A < 0xFFFFFFFF; ++A) {
if((A^((A >> 2) + (A << 5) + C)) == inHash) {
*_C = C;
*_A = A;
return true;
}
}
A = 0;
}
return false;
}
bool findCollisions(unsigned int inHash, char* szOutStr) {
const unsigned int REQ_HASH = 0x12345678;
unsigned int prevHash = 0;
int curChar = 0;
do {
printf("Loop Begin:\tI = %i | H = %08x | rH = %08x\n", curChar, inHash, REQ_HASH);
if(!findSolutions(inHash, &szOutStr[curChar], &prevHash)) {
printf("Unable to find solutions for %08x\n", inHash);
if(curChar == 0) return false;
--curChar;
continue;
}
if(prevHash == REQ_HASH) {
szOutStr[curChar] = 0;
return true;
}
printf("Found solution:\tC = %02x (%c) | A = %08x\n", szOutStr[curChar], szOutStr[curChar], prevHash);
char firstSolutionC = szOutStr[curChar];
unsigned int firstSolutionA = prevHash;
printf("Trying to find alternative solutions..\n");
do {
if(!findSolutions(inHash, &szOutStr[curChar], &prevHash)) {
printf("Alternative solution not found!\n");
break;
}
printf("Alternative solution found [%s valid]:\tC = %02x (%c) | A = %08x\n", prevHash == REQ_HASH ? "" : "not", szOutStr[curChar], szOutStr[curChar], prevHash);
if(prevHash == REQ_HASH) {
szOutStr[curChar] = 0;
return true;
}
++prevHash;
} while(true);
szOutStr[curChar] = firstSolutionC;
prevHash = firstSolutionA;
printf("Using first solution:\tC = %02x (%c) | A = %08x\n", szOutStr[curChar], szOutStr[curChar], prevHash);
++curChar;
inHash = prevHash;
} while(curChar < 127);
return false;
}
int main(void) {
char mask[] = "hQh";
DWORD original = originalHash(mask);
printf("%s == %08x\n", mask, original);
char out[128];
memset(out, 0, sizeof out);
if(findCollisions(original, out))
printf("%08x == %s\n", original, out);
else
printf("Unable to find collisions\n");
getch();
return 0;
}
感謝您的回答,我會測試它。但是請注意,C是BYTE,不等於0(字節的極限是0-255)。正如你所看到的那樣,輸出字符串可以有多個字節C. – RIscRIpt 2013-02-19 22:02:48
你能描述一下你在找什麼嗎?是否像「如果我將ASCII字符串」password「作爲參數」in「傳遞給函數X,我得到的結果是X = 0x60335d1b。我如何取0x60335d1b並找到任意的」in「來產生相同的結果?」 – GalacticJello 2013-02-20 16:55:04
GalacticJello,是的。我正在尋找它。 – RIscRIpt 2013-02-20 16:58:14