Bigger Example 2: Simple Text File Encryption and Decryption

Question: Design a program that can encrypt and decrypt a text file using a simple encryption algorithm. The user should be able to provide a key for encryption, and the program should output the encrypted text to a new file. Another option should allow the user to decrypt the file using the same key.

The provided C code implements a basic file encryption and decryption program using Caesar's cipher. This program allows users to specify whether they want to encrypt or decrypt a text file, along with other parameters such as input file, output file, and the shift value for the cipher. The Caesar's cipher is a substitution cipher where each character in the plaintext is shifted by a fixed number of positions in the alphabet.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

void encryptFile(FILE *inputFile, FILE *outputFile, int shift) {
    char ch;

    while ((ch = fgetc(inputFile)) != EOF) {
        if (isalpha(ch)) {
            if (isupper(ch)) {
                ch = (ch + shift - 'A') % 26 + 'A';
            } else {
                ch = (ch + shift - 'a') % 26 + 'a';
            }
        }

        fputc(ch, outputFile);
    }
}

void decryptFile(FILE *inputFile, FILE *outputFile, int shift) {
    // Decryption is just encryption with a negative shift
    encryptFile(inputFile, outputFile, -shift);
}

void printUsage() {
    printf("Usage: file_encryptor -mode <e/d> -input <input_file> -output <output_file> -shift <shift_value>\n");
    printf("Options:\n");
    printf("  -mode <e/d>          Specify 'e' for encryption or 'd' for decryption.\n");
    printf("  -input <input_file>  Specify the input file.\n");
    printf("  -output <output_file> Specify the output file.\n");
    printf("  -shift <shift_value>  Specify the shift value for encryption/decryption.\n");
}

int main(int argc, char *argv[]) {
    if (argc != 9) {
        printUsage();
        return 1;
    }

    char *mode = argv[2];
    char *inputFileName = argv[4];
    char *outputFileName = argv[6];
    int shift = atoi(argv[8]);

    FILE *inputFile = fopen(inputFileName, "r");
    if (inputFile == NULL) {
        perror("Error opening input file");
        return 1;
    }

    FILE *outputFile = fopen(outputFileName, "w");
    if (outputFile == NULL) {
        perror("Error opening output file");
        fclose(inputFile);
        return 1;
    }

    if (mode[0] == 'e') {
        encryptFile(inputFile, outputFile, shift);
    } else if (mode[0] == 'd') {
        decryptFile(inputFile, outputFile, shift);
    } else {
        printf("Invalid mode. Use 'e' for encryption or 'd' for decryption.\n");
        fclose(inputFile);
        fclose(outputFile);
        printUsage();
        return 1;
    }

    fclose(inputFile);
    fclose(outputFile);

    printf("%s completed successfully.\n", (mode[0] == 'e') ? "Encryption" : "Decryption");

    return 0;
}

The program accepts all necessary information from the command line, and you can use the -h option to print the usage information. For example:

./file_encryptor -mode e -input input.txt -output output.txt -shift 3

Code Explanation:

  1. Function Definitions:

    • encryptFile: This function takes an input file, an output file, and a shift value. It reads each character from the input file, shifts alphabetic characters by the specified amount, and writes the result to the output file.

    • decryptFile: This function handles decryption by invoking encryptFile with a negative shift, effectively reversing the encryption process.

    • printUsage: Prints information about the program's usage, including available options and their descriptions.

  2. Main Function:

    • The main function accepts command-line arguments to determine the mode (encryption or decryption), input file, output file, and shift value.

    • It performs basic validation on the command-line arguments and displays usage information if the number of arguments is incorrect or if an invalid mode is provided.

    • The input file is opened for reading, and the output file is opened for writing. Error messages are displayed if file opening fails.

    • Depending on the mode ('e' for encryption or 'd' for decryption), the program calls the respective function (encryptFile or decryptFile) with the specified shift value.

    • After processing, the input and output files are closed, and a success message is printed based on the selected mode.

  3. Usage:

    • The program is intended to be executed from the command line with specific options.

    • Example usage: ./file_encryptor -mode e -input input.txt -output output.txt -shift 3.

    • The -h option can be used to display the usage information.