#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