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.

0
Subscribe to my newsletter

Read articles from Jyotiprakash Mishra directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Jyotiprakash Mishra
Jyotiprakash Mishra

I am Jyotiprakash, a deeply driven computer systems engineer, software developer, teacher, and philosopher. With a decade of professional experience, I have contributed to various cutting-edge software products in network security, mobile apps, and healthcare software at renowned companies like Oracle, Yahoo, and Epic. My academic journey has taken me to prestigious institutions such as the University of Wisconsin-Madison and BITS Pilani in India, where I consistently ranked among the top of my class. At my core, I am a computer enthusiast with a profound interest in understanding the intricacies of computer programming. My skills are not limited to application programming in Java; I have also delved deeply into computer hardware, learning about various architectures, low-level assembly programming, Linux kernel implementation, and writing device drivers. The contributions of Linus Torvalds, Ken Thompson, and Dennis Ritchie—who revolutionized the computer industry—inspire me. I believe that real contributions to computer science are made by mastering all levels of abstraction and understanding systems inside out. In addition to my professional pursuits, I am passionate about teaching and sharing knowledge. I have spent two years as a teaching assistant at UW Madison, where I taught complex concepts in operating systems, computer graphics, and data structures to both graduate and undergraduate students. Currently, I am an assistant professor at KIIT, Bhubaneswar, where I continue to teach computer science to undergraduate and graduate students. I am also working on writing a few free books on systems programming, as I believe in freely sharing knowledge to empower others.