-1

我寫了一個用於密碼和密鑰生成的散列函數,但很快就意識到能夠顛倒散列值是非常有價值的,所以我寫了一個相反的函數,但是它的工作量很大。我不明白爲什麼這個DOESNT工作。爲什麼這個unhash函數不能反轉這個散列?

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

你期望什麼? 1000? – Organis

+0

是的,這是不可能的嗎? – ZxZ

+3

這就是密碼學的重點,實際上:它不應該有可能從哈希中重新創建原始數據。否則,在過去的幾年裏,不是蠻力的,而是它。 – Organis

回答

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

哈希是不可逆的。如果您想要隱藏原始輸入的可逆函數,請改爲使用加密。只要您擁有正確的密鑰,加密就被設計爲可逆的。

已經有衆所周知的密碼和密鑰生成技術。如果你試圖設計自己的版本,那麼他們將是不安全的。這並不重要,所有你想要做的就是把你的小弟弟藏起來。如果你在商業領域工作,那麼你可能會被起訴,所以使用所有標準的現有安全方法。您可能需要研究像PBKDF2或argon2這樣的密鑰派生函數。

相關問題