2011-10-08 50 views
3

我正在研究我的10年級科學博覽會項目,而且我有點碰壁。我的項目正在測試並行性對強制md5密碼哈希的效率的影響。我將使用1,4,16,32,64,128,512和1024線程來計算它測試的密碼組合的數目/秒,以查看其效率。我不確定我是否會做字典暴力或純暴力。我認爲字典會更容易並行化;只需將每個線程的列表分成相等的部分。我還沒有寫出太多的代碼;我只是想在開始編碼之前將其計劃出來。使用多個線程來破解密碼

我的問題是:

  • 是計算測試/秒,以確定基於線程的#性能的最佳方式的密碼組合?

  • 字典或純蠻力?如果純粹的蠻力,你會如何將任務分解成可變數量的線程?

  • 其他建議?

+5

這些聽起來就像那些能夠很好地發現您的科學公平項目答案的問題。 –

+3

@Greg爲了公平起見,他至少分析了問題的範圍是「我已經確定了要回答的問題」的程度,這很好。:-) – corsiKa

回答

6

我並不是想遏制你的熱情,但這已經是一個很好理解的問題。我會盡力解釋下面的內容。但是也許在另一個地區做你的項目會更好。如何「最大限度地提高MD5散列吞吐量」,那麼你就不會僅限於查看線程。

我認爲,當你編寫你的項目時,你需要提供一些分析,以瞭解何時並行處理合適,何時不合適。

每次你的CPU改變到另一個線程時,它必須保持當前的線程上下文並加載新的線程上下文。這種開銷在單線程進程中不會發生(除了像垃圾回收這樣的託管服務)。因此,所有其他方面相同,添加線程不會提高性能,因爲它必須執行原始工作負載加上所有上下文切換。

但是,如果您有多個CPU(核心)可供您使用,則爲每個CPU創建一個線程將意味着您可以並行計算而不會產生上下文切換成本。如果你有比CPU多的線程,那麼上下文切換將成爲一個問題。

有兩類計算:IO界限和計算界限。 IO綁定計算可能會花費大量的CPU週期等待某個硬件(如網卡或硬盤)的響應。由於這種開銷,可以將線程數增加到CPU再次被刷新的點,這可以抵消上下文切換的成本。但是線程的數量是有限制的,超過這個限制,上下文切換將花費比線程花費在IO上更多的時間。

計算約束計算只需要CPU時間進行數字運算。這是密碼破解者所使用的計算方式。計算綁定操作不會被阻塞,因此添加比CPU更多的線程會降低整體吞吐量。

C#ThreadPool已經爲您處理所有這些問題 - 您只需添加任務,並將它們排隊,直到線程可用。新線程僅在線程被阻塞時纔會創建。這樣,上下文切換就會最小化。

我有一個四核機 - 破題到4個線程,對自己的核心每個執行,會或多或少儘可能快地在我的機器可以蠻力密碼。

要認真並行處理這個問題,你需要大量的CPU。我讀過using the GPU of a graphics card來解決這個問題。

有一個攻擊媒介的分析,我寫了here如果它對你有任何用處。彩虹表和處理器/內存權衡將是另一個有趣的領域做的一個項目。

0

在字典和蠻力方法中,問題是Embarrassingly Parallel。 要用n個線程來分解蠻力的問題,只要說前兩個(或三個)字母(「前綴」)爲n個。然後,每個線程都有一組分配的前綴,比如「aa-fz」,它只負責測試其前綴後面的所有內容。

字典在實踐中通常在統計學上稍微好一些,因爲它可以破解更多的密碼,但是由於它包含了所有內容,所以不會錯過目標長度內的密碼。

+0

這假設所有線程的工作速度相同,但情況可能並非如此。包裹分塊的解決方案會更好。 –

2

要回答你的問題: 1)沒有什麼比測試線程性能的最好方法。根據目標問題中每個操作的獨立程度,不同問題與線程的縮放程度不同。所以你可以嘗試字典的東西。但是,當您分析結果時,您得到的結果可能不適用於所有問題。然而,一個非常流行的例子是,人們嘗試使用共享計數器,其中計數器每個線程增加固定次數。

2)蠻力將覆蓋大量的案例。事實上,通過蠻力,可能會有無限的可能性。所以,你可能不得不通過一些約束來限制你的密碼,比如密碼的最大長度等等。分配蠻力的一種方法是爲每個線程分配密碼的不同起始字符。該線程然後測試該起始字符的所有可能的密碼。一旦線程完成其工作,它會得到另一個起始字符,直到您使用所有可能的起始符號。

3)我想給你的一個建議是測試少量的線程。你將達到1024線程。這不是一個好的理念。一臺機器上的內核數量一般是4到10個。因此,儘量不要超過內核數量的巨大數量。因爲,處理器不能同時運行多個線程。每個處理器在任何給定時間都有一個線程。相反,嘗試衡量不同方案的性能,將問題分配給不同的線程。

讓我知道這是否有幫助!

1

一個解決方案,將兩個字典和所有可能的密碼蠻力的工作是使用基於周圍劃分方法將工作納入工作單位。有一個共享對象負責將問題空間分解爲工作單元 - 理想情況下,每個工作的價值爲100毫秒至5秒 - 併爲每個開始的線程提供此對象的引用。然後,每個線程在這樣的循環操作:

for work_block in work_block_generator.get(): 
    for item in work_block: 
    # Do work 

該上只是瓜分了整個工作區爲每一個線程塊中的優勢,先期是,如果一個線程的工作比別人快,也不會失去工作,只是閒着 - 它會拿起更多的塊。

理想的工作項目發電機將有一個接口,調用它時,返回一個迭代器,它本身返回個人密碼進行測試。然後,基於字典的字典從字典中選擇一個範圍,而強力選擇一個前綴來測試每個批次。當然,您需要使用同步原語來停止嘗試抓取工作單元的不同線程之間的比賽。