|
|
@@ -1,8 +1,10 @@ |
|
|
|
#include "hex_to_base64.h" |
|
|
|
#include "hex_to_base64.h" |
|
|
|
#include <string.h> |
|
|
|
#include <assert.h> |
|
|
|
#include <stdio.h> |
|
|
|
|
|
|
|
#define FREQUENT_LETTERS_AMOUNT 5 |
|
|
|
|
|
|
|
void hex_to_base64_text() { |
|
|
|
const char test_buff1[] ="49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d"; |
|
|
|
const char expected_buff1[] ="SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t"; |
|
|
@@ -21,7 +23,6 @@ void hex_to_base64_text() { |
|
|
|
|
|
|
|
memset (output,'\0', 256); |
|
|
|
hex_to_base64(test_buff1, po, strlen(test_buff1) ); |
|
|
|
// printf("%s\n", output); |
|
|
|
assert( memcmp(expected_buff1, output, strlen(expected_buff1)) == 0 ); |
|
|
|
assert( strlen(expected_buff1) == strlen(output)); |
|
|
|
|
|
|
@@ -82,8 +83,156 @@ void xor_strings_test() |
|
|
|
assert( memcmp(out_buf, "746865206b696420646f6e277420706c6179", 36) == 0); |
|
|
|
} |
|
|
|
|
|
|
|
int char_in_array(const unsigned char iX, const char* const iArray, const size_t iSize ) |
|
|
|
{ |
|
|
|
int found = 0; |
|
|
|
for(size_t i=0; i<iSize; ++i) |
|
|
|
{ |
|
|
|
if(iX==iArray[i]) |
|
|
|
{ |
|
|
|
found = 1; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
/* |
|
|
|
if( !found) |
|
|
|
printf("Nie mam znaka %c\n", iX); |
|
|
|
*/ |
|
|
|
return found; |
|
|
|
} |
|
|
|
|
|
|
|
struct frequency_t { |
|
|
|
char letter; |
|
|
|
unsigned long frequency; |
|
|
|
unsigned long score; |
|
|
|
}; |
|
|
|
|
|
|
|
void fill_frequency(struct frequency_t (&i_frequency_array)[FREQUENT_LETTERS_AMOUNT]) |
|
|
|
{ |
|
|
|
// Most frequent letters in english "etaoinshr", |
|
|
|
i_frequency_array[0].letter='e'; |
|
|
|
i_frequency_array[0].frequency=12; |
|
|
|
i_frequency_array[0].score=0; |
|
|
|
|
|
|
|
i_frequency_array[1].letter='t'; |
|
|
|
i_frequency_array[1].frequency=9; |
|
|
|
i_frequency_array[1].score=0; |
|
|
|
|
|
|
|
i_frequency_array[2].letter='a'; |
|
|
|
i_frequency_array[2].frequency=8; |
|
|
|
i_frequency_array[2].score=0; |
|
|
|
|
|
|
|
i_frequency_array[3].letter='o'; |
|
|
|
i_frequency_array[3].frequency=8; |
|
|
|
i_frequency_array[3].score=0; |
|
|
|
|
|
|
|
i_frequency_array[4].letter='i'; |
|
|
|
i_frequency_array[4].frequency=7; |
|
|
|
i_frequency_array[4].score=0; |
|
|
|
} |
|
|
|
|
|
|
|
void set1_challenge3() |
|
|
|
{ |
|
|
|
static const char ciphertext[] = "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736"; |
|
|
|
static const size_t ciphertext_len = sizeof(ciphertext)/sizeof(char) / 2; |
|
|
|
unsigned char ciphertext_xor[sizeof(ciphertext) / 2]; |
|
|
|
static const char printable_ascii[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,-'+_`?!*:;$ "; |
|
|
|
static const unsigned printable_ascii_len = sizeof(printable_ascii)/sizeof(char); |
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------- |
|
|
|
// |
|
|
|
// Array keeps letters that occure most frequently in english language. They are |
|
|
|
// ordered from most frequent to least frequent |
|
|
|
// |
|
|
|
// ----------------------------------------------------------------------------- |
|
|
|
struct frequency_t frequency[FREQUENT_LETTERS_AMOUNT]; |
|
|
|
fill_frequency(frequency); |
|
|
|
printf("Frequencies "); |
|
|
|
for(int i=0; i<FREQUENT_LETTERS_AMOUNT; ++i) |
|
|
|
printf("%c %d, ",frequency[i].letter, frequency[i].frequency); |
|
|
|
printf("\n"); |
|
|
|
|
|
|
|
// Keeps ID of last valid element in the xors_to_ascii table |
|
|
|
int xorable = 0; |
|
|
|
char xorable_chars[printable_ascii_len]; |
|
|
|
|
|
|
|
// convert ciphertext to HEX |
|
|
|
unsigned char* p_ciphertext_xor = ciphertext_xor; |
|
|
|
convert_string_to_hex(ciphertext, ciphertext_len*2, p_ciphertext_xor); |
|
|
|
|
|
|
|
// for each character in printable check if __full__ ciphertext xors to some readable format |
|
|
|
unsigned char tmp[printable_ascii_len][printable_ascii_len]; |
|
|
|
for(int i=0; i<printable_ascii_len; ++i) |
|
|
|
{ |
|
|
|
char tmp_hex[ciphertext_len]; |
|
|
|
char aXorChar = printable_ascii[i]; |
|
|
|
int fully_coppied=1; |
|
|
|
for(int j=0; j<ciphertext_len; ++j) |
|
|
|
{ |
|
|
|
const unsigned char X = ciphertext_xor[j]^aXorChar; |
|
|
|
if( char_in_array(X, printable_ascii, printable_ascii_len) == 0) |
|
|
|
{ |
|
|
|
fully_coppied=0; |
|
|
|
break; |
|
|
|
} |
|
|
|
tmp[xorable][j] = X; |
|
|
|
} |
|
|
|
if(fully_coppied) |
|
|
|
{ |
|
|
|
xorable_chars[xorable] = aXorChar; |
|
|
|
xorable++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// now choose the strign with biggest number of most frequent letters |
|
|
|
|
|
|
|
struct frequency_t max_score; |
|
|
|
max_score.frequency=0; |
|
|
|
max_score.letter=0x00; // > is not in the set |
|
|
|
max_score.score = 0; |
|
|
|
|
|
|
|
for(int i=0; i<xorable; ++i) |
|
|
|
{ |
|
|
|
unsigned long score=0; |
|
|
|
for(int j=0; j<ciphertext_len; ++j) |
|
|
|
{ |
|
|
|
for(int k=0; k<FREQUENT_LETTERS_AMOUNT; ++k) |
|
|
|
{ |
|
|
|
if(frequency[k].letter == (ciphertext_xor[j]^xorable_chars[i])) |
|
|
|
{ |
|
|
|
score += frequency[k].frequency; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if(max_score.score > 0 && (score == max_score.score) ) |
|
|
|
{ |
|
|
|
printf("Two results with equal scores. Extend number of frequent letters.\n"); |
|
|
|
return; |
|
|
|
} |
|
|
|
else if(score > max_score.score) |
|
|
|
{ |
|
|
|
max_score.score = score; |
|
|
|
max_score.letter = xorable_chars[i]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if(max_score.score > 0) |
|
|
|
{ |
|
|
|
printf("\nLetter used is: %c\n", max_score.letter); |
|
|
|
for(int i=0; i<ciphertext_len; ++i) |
|
|
|
{ |
|
|
|
printf("%c", ciphertext_xor[i]^max_score.letter); |
|
|
|
} |
|
|
|
printf("\n"); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
int main() { |
|
|
|
hex_to_base64_text(); |
|
|
|
convert_string_to_hex_test(); |
|
|
|
xor_strings_test(); |
|
|
|
set1_challenge3(); |
|
|
|
} |