diff options
| author | Benedict <benedict@0xb8000.de> | 2016-03-03 21:49:01 +0100 |
|---|---|---|
| committer | Benedict <benedict@0xb8000.de> | 2017-02-21 13:00:24 +0100 |
| commit | bd7b98c2aac8fdfd128aff832c663d60d3374d63 (patch) | |
| tree | 45b71ac2935cbf9f64e6e892b912868990af7c75 /lib.c | |
| parent | 383732972f4c00dce231f61ac7375ae212e0d9c7 (diff) | |
reorgantzied code into libaray file
For every task you may create a new file and implenet the task there by
using functions from the lib.c file.
Added Makefile for the different tasks.
Diffstat (limited to 'lib.c')
| -rw-r--r-- | lib.c | 378 |
1 files changed, 378 insertions, 0 deletions
@@ -0,0 +1,378 @@ + +#include "lib.h" + +static const unsigned char base64_encode[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +static const unsigned char hex_encode[] = + "0123456789abcdef"; + + + +/** + * teset wheter a bit on the given position is 1 + */ +static int bit_on(char test, int bit) +{ + char tmp; + tmp = 1 << bit; + tmp = test & tmp; + tmp = tmp >> bit; + + return (int) tmp; +} + + +/** + * returns true if the given string contains only printable or whitespace + * characters + */ +static int isprintable(char *string, int length) +{ + int i; + + for(i=0;i<length;i++) { + if(!(isprint(string[i]) || isspace(string[i]))) { + return 0; + } + } + + return 1; +} + + +/* + * task the first three characters of encode and tranform it into the coresponding + * for bytes in base64 and stores it in result +*/ +static void three_bytes_to_base64(char * encode, int bytes_to_print, char *result) +{ + unsigned char one, two, three, four; + unsigned char tmp; + char ret[4]; + + // first six bits + one = encode[0] >> 2; + ret[0] = base64_encode[one]; + if(bytes_to_print-- > 0) + result[0] = ret[0]; + // second six bits + // two last bits of first byte + tmp = encode[0] & 0x03; + two = encode[1] >> 4; + tmp = tmp << 4; + two = tmp | two; + ret[1] = base64_encode[two]; + if(bytes_to_print-- > 0) + result[1] = ret[1]; + // second six bits + // two last bits of first byte + // third six bits + tmp = encode[1] & 0x0F; + tmp = tmp << 2; + three = encode[2] & 0xC0; + three = three >> 6; + three = tmp | three; + ret[2] = base64_encode[three]; + if(bytes_to_print-- > 0) + result[2] = ret[2]; + // last six bit11s + four = encode[2] & 0x3F; + ret[3] = base64_encode[four]; + ret[4] = '\0'; + if(bytes_to_print-- > 0) + result[3] = ret[3]; +} + +/** + * Transform four base64 encoded characters back to three bytes + */ + +void decode_base64(char *string1, char *result) +{ + char one, two, three, tmp; + // first byte is first six bits of base64 one and 2 bit of base64 second + one = string1[0] << 2; + one = one & 0xFC; + tmp = string1[1] >> 4; + tmp = tmp & 0x03; + one = one | tmp; + + // second byte 4 bits of second base64 + 4 bits of third base64 + two = string1[1] << 4; + tmp = string1[2] >> 2; + two = two | tmp; + + // third byte 2 bits of third base54 + 6 bits of fourth base64 + three = string1[2] << 6; + tmp = string1[3]; + three = three | tmp; + + printf("%c%c%c", one, two, three); +} + +static char string_to_hex_map[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F}; +/* + * This function converts the first char of a string into its corresponding + * hex value + * + * @return on Sucess return 0, if char is no valid hex value returns -1 + */ +static int hex_char_to_bit(char toEncode) +{ + char encode; + switch(toEncode) { + case '0': + encode = string_to_hex_map[0]; + break; + case '1': + encode = string_to_hex_map[1]; + break; + case '2': + encode = string_to_hex_map[2]; + break; + case '3': + encode = string_to_hex_map[3]; + break; + case '4': + encode = string_to_hex_map[4]; + break; + case '5': + encode = string_to_hex_map[5]; + break; + case '6': + encode = string_to_hex_map[6]; + break; + case '7': + encode = string_to_hex_map[7]; + break; + case '8': + encode = string_to_hex_map[8]; + break; + case '9': + encode = string_to_hex_map[9]; + break; + case 'a': + encode = string_to_hex_map[10]; + break; + case 'b': + encode = string_to_hex_map[11]; + break; + case 'c': + encode = string_to_hex_map[12]; + break; + case 'd': + encode = string_to_hex_map[13]; + break; + case 'e': + encode = string_to_hex_map[14]; + break; + case 'f': + encode = string_to_hex_map[15]; + break; + default: + return -1; + } + + return encode; + +} + +/** + * takes the first two hex characters of start and convert them to one byte + * with the coressponding value of the two hex chars + */ +static void two_char_hex(char *start, char *result) +{ + char first = hex_char_to_bit(start[0]); + char second = hex_char_to_bit(start[1]); + + *result = first; + *result = *result << 4; + *result = *result | second; +} + +/** + * xor agianst a key. if the length of key is less than the length of + * str1 than the key will be repeated + * @param str1 string which should be xored agianst the given key + * @param key + * @param result buffer where the result is stored + */ +void xor_string(char *str1, char *key, char *result) +{ + int i, j; + int length_key = strlen(key); + + for(i=0, j=0;i<strlen(str1);i++,j++) { + if (j >= length_key) + j = 0; + + result[i] = str1[i] ^ key[j]; + } + + result[i] = '\0'; +} + + +/** + * transform the bytes in str1 into its correspond printable hex version + * @param str1 binary strewam which should be converted + * @param result buffer where the results should be stored + * @param length legnth of str1 + */ +void hex_binary_to_string(char *str1, char *result, int length) +{ + int i; + int tmp = 0; + + for(i=0;i<length/2;i++) { + tmp = str1[i] & 0xF0; + tmp = tmp >> 4; + result[i*2] = hex_encode[tmp]; + tmp = str1[i] & 0x0F; + result[(i*2)+1] = hex_encode[tmp]; + } + + result[i*2] = '\0'; +} + +/** + * takes a hex string and converts it to its correspond binary counterpart + */ +int decode_hex_string(char *encode, char* result) +{ + int i; + int length = strlen(encode); + + for(i = 0;i< length/2;i++) + two_char_hex(&encode[i*2], &result[i]); + + return i; +} + +/** + * counts the frequent characters in a string an divide the number through the + * total number of characters + * @param string string where the frequent characters should be counted + * @param length length of string + * @return number between 0 and 100 (percentage) of frequent characters + */ + +static int score_based_on_frequent_characters(char *string, int length) +{ + int number = 0; + int i; + char tmp; + + for(i=0;i<length;i++) { + tmp = tolower(string[i]); + if( tmp == 'e' || tmp == 'a' || tmp == 'i' || tmp == 'o' + || tmp == 'u' ) + number++; + } + + return ((number*100)/length); +} + +/** + * encode the given string into base64 and stores it in result + */ + +int encode_to_base64(char *encode, char *result) +{ + int length = strlen(encode); + + int rounds = length / 3; + int bytes_last_round = length % 3; + int i; + + for (i=0;i<rounds;i++) { + three_bytes_to_base64(encode + i*3,4, &result[i*4]); + } + // in der letzen runde nicht mehr alle ausgeben + // nur noch 3-leftover + if (bytes_last_round > 0) { + three_bytes_to_base64(encode + i*3, 1+bytes_last_round, &result[i*4]); + + for(i=0;i<(3-bytes_last_round);i++) + result[i*4+(1+bytes_last_round)] = '='; + } + +} + +/** + * prints and base64 encoded string + */ +int print_base64_string(char *string) +{ + // after 76 charactes line break + +} + +/** + * compute the hamming distance (number of different bits) of two string + * @param string1 first string + * @parma string2 second string + * @return returns the hamming distance + */ +int hamming_distance_equal_length(char *string1, char *string2) +{ + char tmp; + int i, j; + int hamming_distance = 0; + + for(i=0;i<strlen(string1);i++) { + tmp = string1[i] ^ string2[i]; + for(j = 0; j < 8; j++) { + if ( bit_on(tmp, j)) + hamming_distance++; + } + } + return hamming_distance; +} + +/** + * returns true if the given strings may represent human language + */ +int string_looks_like_it_is_human_language(char *string, int length) +{ + // string has to be printable and a score bigger than 20 + // to be assumed to be human language + if (!isprintable(string, length)) + return 0; + if (score_based_on_frequent_characters(string, length) < 20) + return 0; + + return 1; +} + +/** + * test every byte on the string as key and returns the found keys + */ +int brute_force_single_byte_xor(char *string, int length, char* keys) +{ + int i, number_found_keys=0; + char *xor_tmp; + char single_byte_key; + + xor_tmp = malloc(length); + + for(i=1;i<255;i++) { + single_byte_key = (char) i; + xor_string(string, &single_byte_key, xor_tmp); + if (string_looks_like_it_is_human_language(xor_tmp, length)) { + keys[number_found_keys++] = single_byte_key; + printf("%s\n", xor_tmp); + } + } + keys[number_found_keys] = '\0'; + + return number_found_keys; +} + + |
