2014-10-07 22 views
-2

我只是無法擺脫我最初認爲會比較簡單的算法。簡單的算法在delphi中破解4個數字的密碼

基本上,用戶輸入一個4長度的數字組合(0 - 9),我想要一個算法,它會嘗試每個可能的組合,直到它匹配用戶輸入的組合。

正如我所說,它可能很簡單,但嵌套循環或其他東西,但我不能得到我的頭。

感謝任何幫助。順便說一句,我正在使用delphi。

+0

好吧,有10^4個可能的組合......我個人會嘗試設置一個零數組n [i],並有4個嵌套循環與單獨的索引變量...如果我知道任何關於德爾福,也許我' d畫一張圖...聽起來像是一個相當奇怪的需求 – beauXjames 2014-10-07 20:14:30

+0

Grover算法是最好的。 :) http://en.wikipedia.org/wiki/Grover%27s_algorithm – kludg 2014-10-07 22:12:39

+1

'我只是無法繞過它 - iirc這是2001年流行的流行歌曲嗎? – mjn 2014-10-08 11:25:42

回答

4
for i := 1 to 9999 do 
    TryCombo(i); 

沒有必要做嵌套循環。如果你需要字符形式的話,使用IntToStr比使用組合和嵌套循環更容易。如果必須進行填充,然後使用一個簡單的墊環:

s:= inttostr(i); 
    while length(s) < 4 do 
    s := '0' + s; 
+0

焊盤循環次優。如果長度小於4,則將while循環替換爲s:= Copy('0000',1,4-Length(s))+ s;'或者使用適當的Format() IntToStr()' – JensG 2014-10-07 20:39:01

+0

是和不是。儘管在大循環中循環不太理想,但簡單的軟件往往是不同的: 代碼: 對於i:= 0到1000000 do //百萬 開始 s:= IntToStr(i);當長度<4時 s:='0'+ S; 結束; vs for i:= 0 to 1000000 do s:=格式('%。4d',[i]); 和定時到高精度定時器給我: 百萬IntToStr:0.0728s 百萬格式:0.1045s 在我的i7。 用7替換4圖形格式,它們大致相同。在11個字符墊上,格式化前面的邊緣。所以,你知道,取決於。 – 2015-05-09 16:59:44

6

的問題似乎問如何使用數字'0''9'生成所有4位數字的字符串。

您可以用for循環和呼叫容易做到這Format

for i := 0 to 9999 do 
    str := Format('%.4d', [i]); 

格式字符串的精度說明確保字符串被補零。

1

雖然@Simpson Bart答案是針對您的特定問題的最快解決方案,但我有一種感覺,您可能是一名計算機科學專業的學生,​​並且您已將這項任務作爲家庭作業。

如果是這種情況,我認爲你的老師/ proffesor可能希望看到你實現了一個自定義計數器,你將測試所有可能的組合,直到找到合適的組合。
以這種方式查找密碼時,這稱爲暴力攻擊。

那麼你如何做到這一點?

首先考慮數學和使用不同的數字系統。爲什麼?爲了實現自定義計數器,您必須創建自定義數字系統。數字系統的基數是密碼中可用字符的數量。在你的情況下,是10(0,1,2,3,4,5,6,7,8,9)。

你必須做的第二件事是創建一個包含所有可能字符的字符串。我們稍後使用它來通過索引來查找特定字符,這些索引是字符串中的位置。

然後,您只需在新的數字系統中計數並通過從包含所有可能字符的字符串中指定特定字符來生成可用的密碼。您可以通過讀取特定字符來完成此操作,該特定字符的位置取決於數字系統中特定數字的值。

最後,您測試以查看生成的密碼是否與您正在尋找的密碼相同。

我希望我對你應該如何解決這個問題的解釋是可以理解的,因爲我不是說當地人講英語的人,所以我可能沒有以最好的方式表達自己。

如果不是,我還在下面發佈了一個代碼示例,其中可能更容易理解。

const 
    //String containing all possible lower case leters and numbers of english alphabet 
    CPossibleLowercaseLetersNumbersChars: AnsiString = 'abcdefghijklmnopqrstuvwxz'; 
    //String containing all possible chars used in HexDecimal numeral system 
    CPossibleHexChars: AnsiString = 'abcdef'; 

implementation 

function BruteForcePasswordFinder(InputStr: AnsiString; PossibleChars: AnsiString): AnsiString; 
var Num1, Num2, Num3, Num4: Integer; //Could use Byte (integer from 0 to 255) instead 
    //String for temporary storing password string we generate 
    TempPassString: AnsiString; 
begin 
    //Set initial conditions 
    Num1 := 0; 
    Num2 := 0; 
    Num3 := 0; 
    Num4 := 0; 
    Result := ''; 
    //Check to see if password is all zeros 
    //First set the legth of temporary password string to have the same number of characters 
    //as possible password 
    SetLength(TempPassString,4); 
    //Set each character of the temporary password string. 
    //We read the characters from an array storing all posible hcaracters by specifying characters 
    //index position in that array 
    //NOTE Unless you are using newer versions of Delphi and compiling for Android first character 
    //in string has index of 1 so we have to add 1 to the Num1, Num2, Num3, Num4 value 
    TempPassString[1] := PossibleChars[Num1+1]; 
    TempPassString[2] := PossibleChars[Num2+1]; 
    TempPassString[3] := PossibleChars[Num3+1]; 
    TempPassString[4] := PossibleChars[Num4+1]; 
    //Check to see if temporary password string matches with the imput password string 
    if TempPassString = InputStr then 
    begin 
    //Set result to matching code 
    Result := TempPassString; 
    //Use Exit call to prematurely end the function so we don't waste time testing 
    //all remaining password combinations 
    Exit; 
    end; 
    //Custom counter implementation 
    while Result = '' do 
    begin 
    //Increase the last number count by one 
    Num4 := Num4+1; 
    //Check to see if the Num4 is greater than specific base number 
    //Base number is number of posible digit representations 
    //- 0 and 1 in Binary numeral system 
    //- 0 to 9 in Decimal numeral system 
    //- 0 to 9 and A B C D E F in HexDecimal numeral system 
    //In our case base number is the number of posible characters (Lenght of PossibleChars) 
    //If it is increase the Num3 and set Num4 to 0 just like you increase tens in Decimal 
    //numeral sytem and stes ones back to 0 
    if Num4 > Length(PossibleChars) then 
    begin 
     Num4 := 0; 
     Num3 := Num3+1; 
     //Check to see if Num3 is greater than specific base number 
     //If it is increase the Num2 by 1 and set Num3 back to 0 
     if Num3 > Length(PossibleChars) then 
     begin 
     Num3 := 0; 
     Num2 := Num2+1; 
     //Check to see if Num2 is greater than specific base number 
     //If it is increase the Num1 by 1 and set Num2 back to 0 
     if Num2 > Length(PossibleChars) then 
     begin 
      Num2 := 0; 
      Num1 := Num1+1; 
     end; 
     end; 
    end; 
    //Prepare temp password string for comparison 
    TempPassString[1] := PossibleChars[Num1+1]; 
    TempPassString[2] := PossibleChars[Num2+1]; 
    TempPassString[3] := PossibleChars[Num3+1]; 
    TempPassString[4] := PossibleChars[Num4+1]; 
    //Check to see if temporary password string matches with the imput password string 
    if TempPassString = InputStr then 
    begin 
     //Set result to matching code 
     Result := TempPassString; 
     //Use Exit call to prematurely end the function so we don't waste time testing 
     //all remaining password combinations 
     Exit; 
    end; 
    end; 
end; 

用法舉例

procedure TForm1.Button1Click(Sender: TObject); 
var FoundPassword: String; 
begin 
    FoundPassword := BruteForcePasswordFinder('59dg',CPossibleLowercaseLetersNumbersChars); 
    ShowMessage('Found password is: '+FoundPassword); 
end; 

免責聲明:爲什麼我把我的代碼到返回找到代碼字符串結果funtion的原因是becouse在實際情況下,你可能不會能夠測試你的密碼反對實際密碼(其他人不需要所有這些),但你可能會檢查是否將密碼密碼提供給其他算法(例如MD5哈希算法)會產生與輸入數據相同的結果(大多數服務器存儲密碼作爲散列表示,從而阻止服務器所有者查看實際上什麼密碼紅)。

+0

Donwvoter你能解釋爲什麼你低估了我的答案。 – SilverWarior 2014-10-08 08:25:30

+0

我做過了,因爲您在答案中提出的解決方案對於要完成的任務來說非常複雜。提問者應該認識到解決方案是基本的:一個單一的循環產生10k個可能的排列。您的解決方案很容易混淆和誤導某人,而沒有執行如此簡單任務所需的基本知識。 (哦,我試圖在當時的評論中解釋它,但不知怎的,引擎並沒有發送它。) – mg30rg 2014-10-08 08:33:51

+0

@SilverWarrior - 評論系統並沒有讓我出於某種原因解決你的問題。我只希望你收到我的回答。 – mg30rg 2014-10-08 09:22:10

1

用Delphi XE7開始,你可以使用新的並行編程庫運行與多線程算法,採用TParallel.For

TParallel.For (lowerBound, upperBound, Method); 

一個例子顯示在http://www.fmxexpress.com/fast-threaded-parallel-for-loop-in-delphi-xe7-firemonkey-on-android-ios-windows-and-osx/

TParallel.For(1, Max, procedure(I: Integer) 
    begin 
    if TryCode(I) then 
    begin 
     WriteLn(I); 
    end 
    end); 

不過我看沒有辦法有條件地終止並行處理。

+0

好的答案,但我必須指出,它指出了原始問題的時代? – mg30rg 2014-10-08 07:55:07

+1

@ mg30rg肯定是的 – mjn 2014-10-08 08:05:51