2016-09-19 90 views
-1

我對cs50編程教程感興趣。在這裏我應該破解一個DES加密的字符串。c - printf(「%s」)打印一個額外的@

首先我專注於創建一個64位大數組,其中包含鹽中使用的所有可能的字符。

在接下來的步驟中,我將它放到兩個for循環中以打印出這兩個for循環的所有可能組合。這就是我現在所處的位置。

出於調試原因,我只是用printf("%s",salt)打印出來。鹽被定義爲char salt[2]。但由於某種原因,它總是打印出[email protected]xx每次都如預期的變化,我不知道@來自哪裏)。

首先,我認爲它可能會超出陣列的一些奇怪的原因,並從隨機存儲器抓取@。這就是我將它從在線IDE複製到本地XCode的原因。仍然是相同的@符號。而現在我很困惑從@來自哪裏。

Link to my code.

#include <cs50.h> 
#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 

#define _XOPEN_SOURCE  // DES - implementation 
#include <unistd.h> 

// shorthands 
#define cypher argv[1] 

#define ascii_dot 46 
#define ascii_slash 47 
#define ascii_zero 48 
#define ascii_nine 57 
#define salt_size 64 

#define majA 65 
#define majZ 90 

#define minA 97 
#define minZ 122 

int main(int argc, string argv[]) { 
    // Checking input 
    if (argc != 2) { 
     printf("<usage>\n<./crack <password_hash>"); 
     return 1; 
    } 

    // Create a salter 
    // 2 * 26 for letters + 10 for numbers + dot and slash = 64 = salt_size 
    char salt_crystal[salt_size]; 

    { // Own scope to not waste space for salt_iterator 
     int salt_iterator = 0; // used to create salt crystals 

     //minuscels 
     for (int i = minA; i <= minZ; i++) 
      salt_crystal[salt_iterator++] = (char)i; 
     //majuscels 
     for (int i = majA; i <= majZ; i++) 
      salt_crystal[salt_iterator++] = (char)i; 
     //ascii_dot to 9 
     for (int i = ascii_dot; i <= ascii_nine; i++) 
      salt_crystal[salt_iterator++] = (char) i; 
    } 

    // make the salt and forward it to the next function 
    for (int i = 0, l = salt_size; i < l; i++) { 
     char salt[2]; 
     salt[0] = salt_crystal[i]; 
     for (int i2 = 0, l2 = salt_size; i2 < l2; i2++) { 
      salt[1] = salt_crystal[i2]; 
      printf("%s ", salt); // DEBUG 
     } 
    } 
} 
+0

感謝您分享您的代碼。 –

+6

'salt'不是以NUL結尾的字符串,您正在讀取未初始化的內存。 'printf(「%c%c」,salt [0],salt [1]);'應該完成這項工作。 –

+0

@AndreaBiondo將答案添加爲答案,而不是評論!我會upvote。 –

回答

5

您還沒有發佈任何代碼,但我猜你沒空終止傳遞給printf()陣列...

編輯好猜測:您可以設置將2個字符轉換爲char salt[2]並將其傳遞給printfprintf會打印這些字符串,並繼續從salt數組末尾讀取內存中的字符,直至找到字符串結尾的'\0'字節。

有不同的方法來解決這個問題:人物後

  • 可以使陣列較長,並設置一個'\0'

    char salt[3]; 
    ... 
    salt[2] = '\0'; 
    printf("%s", salt); 
    
  • 您可以在使用的2精度值printf格式打印最多2字節從陣列:

    printf("%.2s", salt); 
    
  • 可以從陣列打印單個字節:

    putchar(salt[0]); 
    putchar(salt[1]); 
    

至於爲什麼你始終得到一個@,也沒有明確的答案,因爲你遇到不確定的行爲,所以任何事情都有可能發生.. 。但請注意,@的值爲64,這是您存儲在本地變量l中的值。在l變量之前,salt陣列可能位於內存正確位置。在小端中,值64存儲在l的第一個字節中。

另請注意,不建議將變量名稱l用於變量,因爲使用固定字體很難區分數字1

+0

它的工作原理。萬分感謝。仍然需要等幾分鐘才能給你最好的答案。不過,我很困惑,爲什麼每當在兩種不同的環境中嘗試它時,它就是@符號。任何想法呢? – TheCommoner282

+0

@ TheCommoner282這是不值得試圖找出未定義的行爲的結果,除非它已經引起副作用,修復現已消失,但令人滿意地解釋了爲什麼沒有*另一個錯誤導致次要問題。 –

+0

@chqrlie這很有道理。很好的解釋。謝謝:) – TheCommoner282