|
/** |
|
* cetasyn - 10 Dec 20 |
|
* |
|
* Finds characters that do not appear in groups together and prints the sets |
|
* Does not de-duplicate, sort, find delimiters, or bruting decryption |
|
* Run using c_solve.py wrapper for dedup and brute |
|
*/ |
|
|
|
// $ gcc -Wall -pedantic -o setsolve setsolve.c |
|
// $ ./setsolve jmrxy encoded.txt |
|
|
|
#include <errno.h> |
|
#include <stdio.h> |
|
#include <string.h> |
|
#include <sys/stat.h> |
|
#include <sys/types.h> |
|
|
|
#define FILE_BUF_SZ 2048 |
|
#define ABET_LEN 26 |
|
#define DELIM_LEN 5 |
|
#define ALPHA_START 97 |
|
|
|
/** |
|
* Print usage message to stderr |
|
*/ |
|
void print_usage(char* path) |
|
{ |
|
fprintf(stderr, "Usage: %s <delimiters{5}> <path>\nExample: %s vwxyz ./message.txt\n", |
|
path, |
|
path); |
|
} |
|
|
|
/** |
|
* Alters a letter buffer to set a specified character to space |
|
*/ |
|
void lbuf_spc_char(char* letter_buf, char c) |
|
{ |
|
char* c_loc = strchr(letter_buf, c); |
|
if (c_loc) { |
|
*c_loc = ' '; |
|
} |
|
} |
|
|
|
/** |
|
* Returns non-space character count until \0 |
|
*/ |
|
unsigned int nonspc_strcnt(char* str) { |
|
unsigned int count = 0; |
|
while(*str) { |
|
if(*str != ' ') { |
|
count++; |
|
} |
|
str++; |
|
} |
|
return count; |
|
} |
|
|
|
/** |
|
* Prints a string while removing all spaces |
|
*/ |
|
void nonspc_print(char* str) { |
|
while(*str) { |
|
if(*str != ' ') { |
|
putc(*str, stdout); |
|
} |
|
str++; |
|
} |
|
} |
|
|
|
int main(int argc, char* argv[]) |
|
{ |
|
if (argc != 3) { // Verify correct number of args |
|
print_usage(argv[0]); |
|
return -1; |
|
} |
|
if (strlen(argv[1]) != DELIM_LEN) { // Verify correct delimiter string length |
|
fprintf(stderr, "%i delimiters characters required\n", DELIM_LEN); |
|
print_usage(argv[0]); |
|
return -1; |
|
} |
|
|
|
FILE* f = fopen(argv[2], "r"); // File pointer |
|
if (!f) { // Verify successful file open |
|
int err = errno; |
|
fprintf(stderr, "Failed to open: %s - %s\n", argv[2], strerror(err)); |
|
return -1; |
|
} |
|
|
|
char bits_delim[6] = { 0 }; // Delimiter bits |
|
strncpy(bits_delim, argv[1], DELIM_LEN); |
|
|
|
char contentbuf[FILE_BUF_SZ]; // Encoded text file content buffer |
|
fscanf(f, "%s\n", contentbuf); // Read file contents |
|
|
|
// Create and fill alphabet letter solve buffers |
|
char letters_buf[ABET_LEN][ABET_LEN + 1]; |
|
for (int a = 0; a < ABET_LEN; a++) { |
|
strcpy(letters_buf[a], "abcdefghijklmnopqrstuvwxyz\0"); |
|
} |
|
|
|
// Pre-remove delimiters |
|
for (int a = 0; a < ABET_LEN; a++) { |
|
for (int dc = 0; dc < DELIM_LEN; dc++) { |
|
lbuf_spc_char(letters_buf[a], bits_delim[dc]); |
|
} |
|
} |
|
|
|
char* token; // Pointer to representation of encoded character |
|
char* psub = contentbuf; // Pointer to delimiter position in content buffer |
|
// Iterate over delimiters |
|
for (;; psub = NULL) { |
|
token = strtok(psub, bits_delim); |
|
if (token == NULL) { |
|
break; |
|
} |
|
|
|
// Iterate over characters in token - index of letter_buf |
|
int tok_len = strlen(token); |
|
for (int i_lb = 0; i_lb < tok_len; i_lb++) { |
|
// Iterate again, remove all other characters from representative array |
|
for (int i_c = 0; i_c < tok_len; i_c++) { |
|
if (i_lb == i_c) { |
|
continue; // Don't remove self |
|
} |
|
lbuf_spc_char( |
|
letters_buf[(*(token + i_lb) - ALPHA_START)], // Index of letter buf by iter position offset |
|
*(token + i_c)); // Letter by iter position offset |
|
} |
|
} |
|
} |
|
|
|
// Print sets of 3 |
|
for (int a = 0; a < ABET_LEN; a++) { |
|
if (nonspc_strcnt(letters_buf[a]) == 3) { |
|
nonspc_print(letters_buf[a]); |
|
printf("\n"); |
|
} |
|
} |
|
|
|
fclose(f); |
|
return 0; |
|
} |