2016-01-06 42 views
1

是否有可能使此算法的逆向過程?基於字符串創建的反向號碼

int EDI = 0x1505; 
for(int i = 0; i < lstrlen(dir); i++) 
{ 
    if (dir[i] != '.' && dir[i] != '\') 
    { 
    EDX = EDI * 32; 
    EDX = EDX + EDI; 
    EDX = EDX + dir[i]; 
    EDI = EDX; 
    } 
} 

dir是一個字符串,例如,當dir是 「數據\ etcobject \ damagecri.nif」 該函數的輸出將是:1C9EA36C

有沒有辦法檢索只給出輸出編號的原始字符串?

+0

'dir'是'struct'還是別的東西? C不是C++,沒有'std :: string'對象。 –

+0

我編輯了代碼。 –

回答

4

您不能扭轉此功能,因爲它是有損的;它比輸入位具有更少的輸出位,所以不可避免地多個輸入將返回相同的輸出。例如,它忽略./,因此輸入ab,a/ba.b將是相同的。

即使您忽略./也沒有辦法;你正在將一個字符串轉換爲一個整數;除了整數之外,還有更多的字符串,所以不可避免地多個字符串將會產生相同的整數。

+0

即使我失去了'.'和'/'字符..有沒有辦法? –

1

有沒有辦法檢索只給出輸出編號的原始字符串?

一般來說:號


注意

EDX = EDI * 32; 
EDX = EDX + EDI; 
// same as 
EDX = EDI *33' 

考慮2串AB與長度2.

The `EDI` generated are 
EDI(A) = 33*A[0] + A[1] + constant 
EDI(B) = 33*B[0] + B[1] + constant 

with `A[0] == 2, A[1] == 3` we get `33*2 + 3 + constant` or `69 + constant` 
with `B[0] == 1, B[1] == 36` we get `33*1 + 36 + constant` or `69 + constant` 

所以與EDI69 + constant我們無法區分2個字符串原件(或許多其他候選者)。


另一種方式看它是我們假設僅使用A-Z:然後用7個或更多個字母字符,有超過pow(26,7) or 8,031,810,176組合和一個int(假定32位)具有最好的4,294,967,296組合。因此無法將所有7個長字符串與32位int區分開來。

0

此:

EDX = EDI * 32; 
EDX = EDX + EDI; 
EDX = EDX + dir[i]; 
EDI = EDX; 

顯然是相同的:

EDX = EDX * 33 + dir[i]; 

因此,這將是唯一可能扭轉字符串時DIR [I]是一個範圍33內(例如0- 32或97 - 129),EDX不會溢出。

所以,如果你可以假設該字符串只有minuscles(這是ASCII 97-122,有可能:

  • 首先,從VAL
  • 減去0x1505然後,計算ch = VAL % 33
  • 計算ch = ch + n*33。以某種方式獲取ch範圍爲97-129,這是下一個字符。
  • VAL減去此字符除以33:從步驟2,直到VAL
  • 迭代是0

這可以通過使成ch ASCII範圍的其他範圍得到進一步提高(例如數字,大寫字母),如果你覺得,計算出的字符不正確。但是,這使得算法啓發式。

另一種方法:如果您有一個候選字符串列表(或者您可以生成一個候選字符串),那麼您可以用它來提供算法並將其與數字進行比較。

+0

你能詳細說明你描述的步驟嗎?我無法理解你爲什麼在做'ch = VAL%33'和'ch = n * 33'之後。 'N'是for循環中使用的變量,對嗎? –

+0

不,n是以從0-32到目標範圍獲得ch的方式選擇的自然數,即如果您正在尋找小寫字母,則爲97-129。所以,如果VAL%33結果爲10,則選擇n = 3將其提升至10 + 3 * 33 = 109。 – Ctx

+0

爲什麼選擇n = 3?我不明白你使用的邏輯。爲什麼不是4或5? –