OP here again, I finally got some time to implement some of the ideas discussed here. I'm very pleased to say that it all, finally, seems to work. And no errors or warnings.
Encryption:
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <string.h>
# include <math.h>
#define arrsize 1802
int main(){
FILE *Keyfile = fopen("/home/USERNAME/keyfile.txt", "r");
char input[arrsize];
puts("Enter your text as a single line, no paragraphs, max 1800 characters. Press Enter when finished.");
fgets(input, 1800, stdin);
size_t k = strlen(input);
if (input[k - 1] == '\n'){
input[k - 1] = '\0';
}
if (k > 1800){
puts("Error, message was >1800 characters. Don't be a fag.");
return 1;
}
else{
printf("\n\nVerifying your text input was length %lu and size %lu...\n", strlen(input), sizeof(input));
for (int i=0; i<k; i++){
printf("%c", input[i]);
}
}
char key[k];
printf("\n\nReading the key.\n");
if (!Keyfile){
printf("Error opening keyfile!");
return 1;
}
else{[Expand Post]
fgets(key, k, Keyfile);
}
printf("Key array is of length %lu with size of %lu\n\n", strlen(key), sizeof(key));
for (int i=0; i<k; i++){
printf("%c ", key[i]);
}
char xor[k];
for (int i=0; i<k; i++){
xor[i] = (char) (input[i] ^ key[i]);
}
printf("\n\nExecuting XOR and storing in xor array of length %lu and size %lu\n\n", strlen(xor), sizeof(xor));
for (int i=0; i<k; i++){
printf("%d ", xor[i]);
}
FILE *Cipher = fopen("/home/USERNAME/ciphertext", "wb");
if(!Cipher){
printf("Error writing to file!");
return 1;
}
else{
printf("\n\nWriting XOR array contents to binary file ciphertext");
fwrite(xor, sizeof(xor), 1, Cipher);
}
fclose(Keyfile);
fclose(Cipher);
printf("\n\n");
return 0;
}
And decrypting:
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <string.h>
# include <math.h>
#define size 1802
int main(){
FILE *Keyfile = fopen("/home/USERNAME/keyfile.txt", "r");
FILE *Cipher = fopen("/home/USERNAME/ciphertext", "rb");
FILE *Plain = fopen("/home/USERNAME/plaintext.txt", "w");
char ciphertext[size];
if (!Keyfile){
printf("Error opening keyfile");
return 1;
}
else if (!Cipher){
printf("Error opening ciphertext!");
return 1;
}
else if (!Plain){
printf("Error opening plaintext!");
return 1;
}
else{
printf("Reading ciphertext into array...\n\n");
fread(ciphertext, 1800, 1, Cipher);
}
fseek(Cipher, 0L, SEEK_END);
size_t j = ftell(Cipher);
rewind(Cipher);
puts("Printing contents of the ciphertext array to verify.");
for (int i=0; i<j; i++){
printf("%d ", ciphertext[i]);
}
char key[j];
printf("\n\nReading the key...\n\n");
fgets(key, j, Keyfile);
printf("Key array is of length %lu with size of %lu\n\n", strlen(key), sizeof(key));
for (int i=0; i<j; i++){
printf("%c ", key[i]);
}
char plain[j];
for (int i=0; i<j; i++){
plain[i] = (char) (ciphertext[i] ^ key[i]);
}
printf("\n\nExecuting XOR and storing in plaintext array of length %lu and size %lu\n\n", strlen(plain), sizeof(plain));
printf("%s", plain);
puts("\n\nOutputting plaintext to plaintext.txt");
fputs(plain, Plain);
printf("\n\nAll done.");
fclose(Keyfile);
fclose(Cipher);
fclose(Plain);
return 0;
}
Lots of validation prints and comment blocks where I was trying different things just to see how they'd behave. I noted pretty quickly that you can't read binary data interpreted as a string because it's never null terminated (not a C string). In setting the read limits for the decryption process I had to make my first use of fseek because strlen was a no-go, but I had already known I was going to have to, so that was gratifying. Both of these programs worked with every combination of inputs I could throw at them, including escaped characters and special cases and natural 0s from the XOR.
As an aside, I've found that C99 is my absolute favorite C iteration. It's a black sheep and normalfags all seem to hate half of what it brought to the table like VLAs. Half of the interesting (to me) quirky little things I read about in C came in C99. I don't care if I'm never a pro at this. just getting these things to work and see the correct output on my computer is entirely rewarding enough.