diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c749891 --- /dev/null +++ b/.gitignore @@ -0,0 +1,53 @@ +# ---> C +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/set1/01_base64.c b/set1/01_base64.c new file mode 100644 index 0000000..82386ca --- /dev/null +++ b/set1/01_base64.c @@ -0,0 +1,57 @@ +#include +#include +#include + +#include "utils.h" +#define INPUT_LEN 200 + +const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +int main() { + char *input = (char*)malloc(INPUT_LEN); + char *output = (char*)malloc((INPUT_LEN / 3 + INPUT_LEN % 3) * 4); + char buf[3]; + char sixtet; + int i; int j; + int n = read_bytes(input, INPUT_LEN); + + // number of byte triples (n_triples * 4 - output size) + int n_triples = n / 3; + // if n is not divided by 3 then we should add one more triple, we will fill remaining bytes with zeroes + if (n % 3) + n_triples++; + + // i - starting number of triple, j - starting number of quadriple + for (i = 0, j = 0; i < 3 * n_triples; i += 3, j += 4) { + // if it's the last triple (maybe not full) + if (i == 3 * n_triples - 1) { + buf[0] = input[i]; + if (n % 3 == 1) + buf[1] = buf[2] = 0; + else if (n % 3 == 2) { + buf[1] = input[i + 1]; + buf[2] = 0; + } + else { + buf[1] = input[i + 1]; + buf[2] = input[i + 2]; + } + } + else { + buf[0] = input[i]; buf[1] = input[i+1]; buf[2] = input[i+2]; + } + sixtet = (buf[0] & 0b11111100) >> 2; + output[j] = b64[(int)sixtet]; + sixtet = ((buf[0] & 0b00000011) << 4) | ((buf[1] & 0b11110000) >> 4); + output[j+1] = b64[(int)sixtet]; + sixtet = ((buf[1] & 0b00001111) << 2) | ((buf[2] & 0b11000000) >> 6); + output[j+2] = b64[(int)sixtet]; + sixtet = buf[2] & 0b00111111; + output[j+3] = b64[(int)sixtet]; + } + for (int k = 0; k < n_triples * 4; ++k) { + printf("%c", output[k]); + } + printf("\n"); + +} diff --git a/set1/02_fixed_xor.c b/set1/02_fixed_xor.c new file mode 100644 index 0000000..93bedac --- /dev/null +++ b/set1/02_fixed_xor.c @@ -0,0 +1,18 @@ +#include +#include +#include "utils.h" + +#define INPUT_LEN 200 +int main() { + char *a = (char*)malloc(INPUT_LEN); + char *b = (char*)malloc(INPUT_LEN); + char *output = (char*)malloc(INPUT_LEN); + + int n = read_bytes(a, INPUT_LEN); + read_bytes(b, INPUT_LEN); + + for(int i = 0; i < n; ++i) { + output[i] = a[i] ^ b[i]; + } + print_bytes(output, n); +} diff --git a/set1/03_single_character_xor.c b/set1/03_single_character_xor.c new file mode 100644 index 0000000..1f7a2fe --- /dev/null +++ b/set1/03_single_character_xor.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include + +#include "utils.h" + +// 'a'-'z', last value is a frequency of non-alphaber symbols +const double eng_freq[] = {0.08167,0.01492,0.02782,0.04253,0.12702,0.02228,0.02015,0.06094,0.06966,0.00153,0.00772,0.04025,0.02406,0.06749,0.07507,0.01929,0.00095,0.05987,0.06327,0.09056,0.02758,0.00978,0.02360,0.00150,0.01974,0.00074,0}; + +void freq(char *str, int n, double* freqs, char min, char max) { + for (int i = 0; i < n; ++i) { + if (str[i] >= min && str[i] <= max) + freqs[str[i] - min]++; + else + freqs[max - min + 1]++; + } + + for (int j = 0; j < max - min + 2; ++j) + freqs[j] /= n; +} + +double std(double *a, const double *b, int n) { + double result = 0; + for (int i = 0; i < n; ++i) + result += (a[i] - b[i]) * (a[i] - b[i]); + result /= n; + return result; +} + +double freq_score(char *str, int n) { + double score = 0; + char* str_copy = (char*)malloc(n); + strncpy(str_copy, str, n); + + // last value is a frequency of non-alphaber symbols + double* freqs = (double*)malloc(('z' - 'a' + 2) * sizeof(double)); + + for (int i = 0; i < n; ++i) + if (str_copy[i] >= 'A' && str_copy[i] <='Z') + str_copy[i] = tolower(str[i]); + + freq(str_copy, n, freqs, 'a', 'z'); + + score = std(freqs, eng_freq, 'z' - 'a' + 2); + free(str_copy); + free(freqs); + return score; +} + +int main() { + char *input = (char*)malloc(34); + read_bytes(input, 34); + + char *result = (char*)malloc(35); + char *buf = (char*)malloc(34); + double score = 0; double min_score = DBL_MAX; + + for (unsigned char i = 0; i < 255; ++i) { + for (int j = 0; j < 34; ++j) + buf[j] = input[j] ^ i; + score = freq_score(buf, 34); + if (score < min_score) { + min_score = score; + strncpy(result, buf, 34); + } + } + result[34] = '\0'; + printf("%s\n", result); + + free(input); free(result); free(buf); +} diff --git a/set1/utils.c b/set1/utils.c new file mode 100644 index 0000000..b679902 --- /dev/null +++ b/set1/utils.c @@ -0,0 +1,35 @@ +#include +#include + +int read_bytes(char *out_byte_array, int max_n) { + char buf[2]; + int i = 0; + while(((buf[0] = (char)getchar())!= EOF) && (buf[0] != '\n') && (i < max_n)) { + buf[1] = getchar(); + if (buf[1] == EOF) + return -1; + sscanf(buf, "%hhx", out_byte_array + i); + i++; + } + // number of read characters + return i; +} +void print_bytes(char *byte_array, int n) { + for (int i = 0; i < n; ++i) { + printf("%hhx", byte_array[i]); + } +} + +int print_str_bytes(char *str, int n) { + for (int i = 0; i < n; ++i) { + printf("%hhx", str[i]); + } + +} +/*int main() { + char meow[10]; + int n = read_bytes(meow, 10); + print_bytes(meow, n); + char *nya = "meow meow ctagirl uwu"; + print_str_bytes(nya, strlen(nya)); +}*/ diff --git a/set1/utils.h b/set1/utils.h new file mode 100644 index 0000000..f9c382f --- /dev/null +++ b/set1/utils.h @@ -0,0 +1,5 @@ +int read_bytes(char *output, int max_n); + +void print_bytes(char *byte_array, int n); + +int print_str_bytes(char *str, int n);