diff --git a/Makefile b/Makefile index 667502879c38cfc7697ac408383a7742947bf3d6..713a2c44f0908058a8721c0511f6d4f21aa4299a 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CC = gcc CFLAGS = -Wall -std=c99 -g # modify the flags here ^ EXE = crack -OBJ = proj-2_sha256.o decrypt.o +OBJ = proj-2_sha256.o decrypt.o hashtable.o # add any new object files here ^ # top (default) target all: $(EXE) @@ -11,7 +11,6 @@ all: $(EXE) $(EXE): $(OBJ) $(CC) $(CFLAGS) -o $(EXE) $(OBJ) -lm - # ^ add any new dependencies here (for example if you add new modules) diff --git a/decrypt.c b/decrypt.c index 534fd48acc7ccdb638a5e08eaf829d4a1b17daa8..64b4b66b2a75a240b8e608621f03ef86c690bad9 100644 --- a/decrypt.c +++ b/decrypt.c @@ -1,4 +1,40 @@ #include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> +char** store_password_hashes(char* hashes){ + char **password_hashes = (char**)malloc((strlen(hashes)/64)*sizeof(char*)); + assert(password_hashes); + memset(password_hashes,0,(strlen(hashes)/64)); + for(int i=1; i <= strlen(hashes)/64; i++){ + password_hashes[i-1] = malloc(sizeof(char)*(64+1)); + assert(password_hashes[i-1]); + memset(password_hashes[i-1],0,strlen(password_hashes[i-1])); + snprintf(password_hashes[i-1], 65, "%s",hashes + (i-1)*64); + } + return password_hashes; +} + +void read_hash_file(FILE *file){ + if (file){ + char hashes[650]; + int n=0; + int c; + while((c = getc(file)) != EOF){ + n +=sprintf(hashes+n,"%02x", c); + } + // printf("%s",hashes); + char **words = store_password_hashes(hashes); + for(int i=0; i < strlen(hashes)/64; i++){ + printf("%d: %s\n", i, words[i]); + free(words[i]); + }; + free(words); + fclose(file); + } +} +void generate_guesses(int n_guesses){ +} int main(int argc, char *argv[]){ FILE *file; @@ -15,16 +51,3 @@ int main(int argc, char *argv[]){ // read file and do stuff } } -void read_hash_file(FILE *file){ - int c; - if (file){ - while((c = getc(file)) != EOF){ - putchar(c); - } - fclose(file); - } -} - - -void generate_guesses(int n_guesses){ -} \ No newline at end of file diff --git a/hashtable.c b/hashtable.c new file mode 100644 index 0000000000000000000000000000000000000000..6052f84d89030fcb190b5f3625ca988529880771 --- /dev/null +++ b/hashtable.c @@ -0,0 +1,176 @@ +/* This hash table has been adapted by Abhisha Nirmalathas. + The original hash table it was adapted from was made + by Matt Farrugia <matt.farrugia@unimelb.edu.au, for Design of Algorithms. + This hash table uses separate chaining with an array. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <string.h> + +#include "hashtable.h" + +typedef struct bucket Bucket; +struct bucket { + char **keys; //array of words + int *values; //array of weighted frequencies, lower value is higher frequency + int capacity; //space available in bucket + int n_elems; //number of elements in bucket +}; + +struct table { + int size; //number of buckets + Bucket *buckets; //list of buckets +}; + +/************************************************************************/ +// moves recently accessed key & value to the front of bucket +void move_to_front(Bucket *bucket, int hash_value); + + unsigned int seed = 73802; + unsigned int xor_hash(const char *key, unsigned int size) { + unsigned int h = seed; + + int i; + for (i = 0; key[i] != '\0'; i++) { + h = h ^ ((h << 5) + key[i] + (h >> 2)); + } + + return h % size; + } +/************************************************************************/ +Bucket *add_to_bucket(Bucket *bucket, char *key, int value) { + /*Adds new key and value to existing bucket*/ + bucket->n_elems = bucket->n_elems + 1; + // allocates more memory if not enough space + if (bucket->capacity <= bucket->n_elems){ + bucket->capacity = 2*(bucket->capacity + 1); + bucket->keys = realloc(bucket->keys,sizeof(char*) * (bucket->capacity)); + bucket->values = realloc(bucket->values,sizeof(int) * (bucket->capacity)); + } + assert(bucket->keys); + assert(bucket->values); + //adds new key and avlue to end of bucket + bucket->values[bucket->n_elems-1] = value; + bucket->keys[bucket->n_elems-1] = key; + return bucket; +} +/************************************************************************/ +// Warning: does not free bucket->next +void free_bucket(Bucket bucket) { + /*Deallocates memory in bucket*/ + free(bucket.keys); + free(bucket.values); +} + + +/************************************************************************/ +HashTable *new_hash_table(int size) { + /*Builds a new hash table of input size*/ + HashTable *table = malloc(sizeof *table); + assert(table); + table->size = size; + table->buckets = malloc(size * (sizeof *table->buckets)); + assert(table->buckets); + int i; + for (i = 0; i < size; i++) { + table->buckets[i].keys = malloc(sizeof(char*)); + table->buckets[i].values = malloc(sizeof(int)); + table->buckets[i].capacity = 0; + table->buckets[i].n_elems = 0; + } + return table; +} +/************************************************************************/ +void free_hash_table(HashTable *table) { + /*Deallocates memory from hash table*/ + assert(table != NULL); + int i; + for (i = 0; i < table->size; i++) { + free_bucket(table->buckets[i]); + } + free(table->buckets); + free(table); +} + +/************************************************************************/ +bool equal(char *a, char *b) { + /*Returns if a string is equal to another string*/ + return strcmp(a, b) == 0; +} + +/************************************************************************/ +void hash_table_put(HashTable *table, char *key, int value) { + /*Inserts new key into hash table with weighted value*/ + assert(table != NULL); + assert(key != NULL); + int hash_value = xor_hash(key, table->size); + // look for existing key + Bucket *bucket = &table->buckets[hash_value]; + for (int i=0; i < bucket->n_elems; i++){ + if (equal(bucket->keys[i], key)){ + bucket->values[i] = value; + move_to_front(bucket, i); + return; + } + } + // adds key and value as not in hash table + bucket = add_to_bucket(bucket, key, value); + table->buckets[hash_value] = *bucket; + move_to_front(bucket, bucket->n_elems - 1); +} +/************************************************************************/ +void move_to_front(Bucket *bucket, int index){ + /*moves recently accessed key & value to the front of bucket*/ + char* temp_key; + int temp_value; + if (bucket->n_elems <= 1 && index >= bucket->n_elems){ + return; + } + // swaps position of first element with recently accessed + temp_key = bucket->keys[index]; + temp_value = bucket->values[index]; + bucket->keys[index] = bucket->keys[0]; + bucket->values[index] = bucket->values[0]; + bucket->values[0] = temp_value; + bucket->keys[0] = temp_key; +} +/************************************************************************/ +int hash_table_get(HashTable *table, char *key) { + /*Checks if key in hash table and returns value if present*/ + int freq = -1; + assert(table != NULL); + assert(key != NULL); + + int hash_value = xor_hash(key, table->size); + + // look for existing key + Bucket *bucket = &table->buckets[hash_value]; + for (int i=0; i < bucket->n_elems; i++){ + if (equal(bucket->keys[i], key)){ + freq = bucket->values[i]; + move_to_front(bucket, i); + break; + } + } + //returns value of key if found, else return -1 + return freq; +} +/************************************************************************/ +bool hash_table_has(HashTable *table, char *key) { + /*Checks if the key exists in hash table*/ + assert(table != NULL); + assert(key != NULL); + + int hash_value = xor_hash(key, table->size); + + // look for existing key + Bucket *bucket = &table->buckets[hash_value]; + for (int i=0; i < bucket->n_elems; i++){ + if (equal(bucket->keys[i], key)){ + return true; + } + } + return false; +} diff --git a/hashtable.h b/hashtable.h new file mode 100644 index 0000000000000000000000000000000000000000..a7bff387af7db8ce86c6d7a97f7ef294fb25023e --- /dev/null +++ b/hashtable.h @@ -0,0 +1,24 @@ +/* This hash table has been adapted by Abhisha Nirmalathas. + The original hash table it was adapted from was made + by Matt Farrugia <matt.farrugia@unimelb.edu.au, for Design of Algorithms. + This hash table uses separate chaining with an array. +*/ +#include <stdbool.h> + +typedef struct table HashTable; + + +//Creates a new hash table of input size +HashTable *new_hash_table(int size); + +//Deallocates memory from hash table +void free_hash_table(HashTable *table); + +//Inserts new key into hash table with weighted value +void hash_table_put(HashTable *table, char *key, int value); + +//checks if key in hash table and returns value if present +int hash_table_get(HashTable *table, char *key); + +//Checks if the key exists in hash table +bool hash_table_has(HashTable *table, char *key);