diff options
| author | Benedict <benedict@0xb8000.de> | 2016-03-19 13:44:55 +0100 |
|---|---|---|
| committer | Benedict <benedict@0xb8000.de> | 2017-02-21 13:00:24 +0100 |
| commit | 4a9770b8ba9d86db12779f5ae00366bce60a42ad (patch) | |
| tree | 760dee07368fa25141e2467d21128486f5e5e7f8 /task6.c | |
| parent | 236d0ee8acedc2535a4a973acd99a708b530a053 (diff) | |
completed task6 nearly completly
just a few characters are still wrong in the key.
freqencies analysis has to be made more comprehensive
Diffstat (limited to 'task6.c')
| -rw-r--r-- | task6.c | 122 |
1 files changed, 100 insertions, 22 deletions
@@ -1,13 +1,42 @@ #include "lib.h" -void main() +/** + * split ciphertext in blocks of size blocksize + * @return returns an array of string of size with blocksize elements + */ + + +char **transpose_blocks(char *ciphertext, int blocksize, int length) { - /*FILE *fp; - int keysize; - char *file_content, *chipertext, *block1, *block2; - int file_size = 61; - int min_hamming_distance; + char **blocks; + int i, j; + int number_blocks = length / blocksize; + + blocks = malloc(blocksize*(sizeof(char*))); + + for(i=0;i<blocksize;i++) { + blocks[i] = malloc(number_blocks+1); + } + for(j=0;j<blocksize;j++) { + for(i=0;i<number_blocks;i++) { + blocks[j][i] = ciphertext[(i*blocksize)+j]; + } + } + + return blocks; +} + +int main() +{ + FILE *fp; + int keysize; + char ch; + char *file_content, *new_file_content, *chiphertext, *block1, *block2; + int file_size = 60, file_pos = 0; + int i; + double min_hamming_distance, tmp; + fp = fopen("6.txt", "r"); if (fp == NULL) { @@ -17,35 +46,84 @@ void main() file_content = malloc(file_size); + if (file_content == NULL) { + perror("out of memory"); + exit(1); + } + // read data and decode it from base64 // result is not a hex strin or? - while (fscanf(fp, "%60c", file_content) != EOF) { - file_size += 61; - file_content = realloc(file_content, file_size); + while ( (ch = fgetc(fp)) != EOF) { + // ignore new lines as this is part of base64 + if (ch == '\n' || ch == '\r') + continue; + + if (file_pos+1 >= file_size) { + new_file_content = realloc(file_content, (file_size+60)); + if (new_file_content != NULL) { + file_content = new_file_content; + file_size += 60; + } + else { + printf("error allocating memory\n"); + exit(1); + } + } + file_content[file_pos++] = ch; } + file_content[file_pos] = '\0'; - ciphertext = malloc(file_size); - decode_base64(file_content, ciphertext); + int ciphertext_len = 0; + + chiphertext = malloc(file_pos+1); + ciphertext_len = decode_base64(file_content, chiphertext); block1 = malloc(41); block2 = malloc(41); - // split ciphertext in blocks of size 2 to 40 - for(keysize=2; keysize < 40; keysize++) { - strncpy(block1, ciphertext, keysize); - strncpy(block2, &ciphertext[keysize+1], keysize); - - tmp = hamming_distance(block1, block2); - tmp = tmp / keysize; + // max. hamming distacne is 100. + min_hamming_distance = 101; - if (tmp < min_hamming_distance) + int j=0; + // split ciphertext in 4 blocks of size 2 to 40 + // and compute hamming distance of these blocks + for(i=2; i <= 40; i++) { + for(j=0;j< ciphertext_len/i;j++) { + memcpy(block1, &chiphertext[j], i); + block1[i+1] = '\0'; + memcpy(block2, &chiphertext[j+i], i); + block2[i+1] = '\0'; + + tmp += (double) hamming_distance_equal_length(block1, block2, i); + } + tmp = ((double)tmp / (double) (ciphertext_len/i)/ (double)i); + if (tmp <= min_hamming_distance) { min_hamming_distance = tmp; + keysize = i; + } } + + int number_blocks = ciphertext_len/keysize; + printf("use keysize: %i with hammind_distance: %f, number of blocks:%i\n", keysize, min_hamming_distance, number_blocks); + // split into keysize blcoks and transpose them + char **transposed_blocks = transpose_blocks(chiphertext, keysize, ciphertext_len); - printf("keysize: %i\n", min_hamming_distance); + char key[keysize+1]; + struct key_and_freq tmp_NOT_USED_HERE; + + for(i=0;i<keysize;i++) { + key[i] = brute_force_single_byte_xor(transposed_blocks[i], + number_blocks, &tmp_NOT_USED_HERE); + } + key[keysize+1] = '\0'; + char *cleartext = malloc(ciphertext_len+1); + // xor with all single byte keys on the whole data + cleartext[ciphertext_len] = '\0'; + xor_string(chiphertext, key, cleartext, keysize, ciphertext_len); - // transpose the blocks -*/ + printf("%s\n", cleartext); + printf("used key: %s\n", key); + return 0; } |
