Created
May 15, 2019 19:42
-
-
Save sdwvit/3200535a68dff3b4f9482a135deda429 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cs50.h> | |
#include <stdio.h> | |
#include <crypt.h> | |
#include <string.h> | |
int A_charcode = 65; | |
int a_charcode = 97; | |
int abc_size = 25; | |
string hash; | |
bool success = false; | |
int iterator = 0; | |
/** | |
* replaces letter with the next one from alphabet | |
* incrementLetter('a') => 'b' | |
*/ | |
char incrementLetter(char letter) | |
{ | |
return (char)((int)letter + 1); | |
} | |
#define ARRAY_CONCAT(TYPE, A, An, B, Bn) \ | |
(TYPE *)array_concat((const void *)(A), (An), (const void *)(B), (Bn), sizeof(TYPE)); | |
/** | |
* concats 2 arrays | |
* ARRAY_CONCAT("abc", "def") => "abcdef" | |
*/ | |
void *array_concat(const void *a, size_t an, | |
const void *b, size_t bn, size_t s) | |
{ | |
char *p = malloc(s * (an + bn)); | |
memcpy(p, a, an * s); | |
memcpy(p + an * s, b, bn * s); | |
return p; | |
} | |
/** | |
* slices array from start to end | |
* slice("abc", 0, 2) => "ab" | |
*/ | |
void *slice(string s1, int start, int end) | |
{ | |
char *t = malloc((end - start) * sizeof(char)); | |
for (int j = 0; j < end - start; j++) | |
{ | |
t[j] = s1[j + start]; | |
} | |
return t; | |
} | |
/** | |
* gives next word based on incrementLetter | |
* getNextWord("abc") => "bbc" | |
*/ | |
string getNextWord(string s1) | |
{ | |
char first_letter = s1[0]; | |
if (first_letter == ' ') | |
{ | |
s1[0] = 'A'; | |
} | |
else if (first_letter == 'Z') | |
{ | |
s1[0] = 'a'; | |
} | |
else if (first_letter < 'z') | |
{ | |
s1[0] = incrementLetter(first_letter); | |
} | |
else if (first_letter == 'z') | |
{ | |
string first_letter_str = slice(s1, 0, 1); | |
first_letter_str[0] = 'A'; | |
string next_word_substr = slice(s1, 1, strlen(s1)); | |
if (!next_word_substr[0]) | |
{ | |
next_word_substr[0] = 'A'; | |
} | |
else | |
{ | |
next_word_substr = getNextWord(next_word_substr); | |
} | |
return ARRAY_CONCAT(char, first_letter_str, 1, next_word_substr, strlen(next_word_substr)); | |
} | |
return s1; | |
} | |
/** | |
* compares 2 strings | |
* equals("abc", "abc") => true | |
* equals("abc", "bcd") => false | |
*/ | |
bool equals(string s1, string s2) | |
{ | |
if (strlen(s1) != strlen(s2)) | |
{ | |
return false; | |
} | |
for (int i = 0; i < strlen(s1); i++) | |
{ | |
if (s1[i] != s2[i]) | |
{ | |
return false; | |
} | |
} | |
return true; | |
} | |
int main(int argc, string argv[]) | |
{ | |
if (argc != 2) | |
{ | |
printf("Usage: ./crack hash\n"); | |
return 1; | |
} | |
hash = argv[1]; | |
char *word = malloc(6 * sizeof(char)); | |
string salt = slice(hash, 0, 2); | |
word[0] = ' '; // special char to start populating word | |
while (!success) | |
{ | |
word = getNextWord(word); | |
success = equals(crypt(word, salt), hash); | |
} | |
printf("word: %s\n", word); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment