Encryption Challenge
5 Jun 2024 | Edited: 10 Dec 2025Create a program that, when given both a file and a (integer) key, encrypts the file by adding together the ASCII code for each character, the character’s index in the file, and the key and then converts that sum to binary. The program should also be able to decrypt any encrypted files it creates. Make the program as fast as possible in the language of your choice.
My Solution
I chose to write my solution in C to make it as fast as reasonably possible without writing Assembly or machine code. At first, I wrote the encrypted messages as ASCII 1s and 0s to the output files. This approach was very slow, so I eventually moved towards simply writing the value of the encrypted character to the file, which, by virtue of this number having some 32 bit value in binary, is “the sum in binary”. This sped up the program tremendously and made the algorithm much simpler. The code for the program is on GitHub.
Encryption
To encrypt a file, I create a character buffer so that fread will read the input file character-by-character.
unsigned char buf; // buf is a single character
while (fread(&buf, sizeof(buf), 1, ifile) == 1) {
...
}
Then, I calculate the encrypted_char from the character’s ASCII code (buf’s value in decimal) + its index + the key. Whatever this number is in binary will be written to the encrypted file.
int encrypted_char = buf + i + key;
fwrite(&encrypted_char, sizeof(encrypted_char), 1 , ofile);
Decryption
Directly writing the encrypted characters to the output file saved me a lot of trouble when decrypting. Rather than having to read 32 ASCII 1s and 0s from a file and store them in an array, I could simply read the exact number of bits I wanted to decrypt.
int buf; // buf is 32 bits
while (fread(&buf, sizeof(buf), 1, ifile) == 1) {
...
}
I made buf an integer, so that the program will read 32 bits at a time into the buffer from the encrypted file. Then, I do the reverse of encryption by subtracting each integer by its index and the key and use fprintf to write the ASCII character for that number to the decrypted file.
buf -= i + key;
fprintf(ofile, "%c", (char) buf);
Printing
The program requires either an -e or -d flag, for encryption or decryption, followed by a key. I also added an optional -v flag, for verbose, to print to the console what the program is writing to the output file. For encryption, I needed to print the binary representation of each integer sum, so I created my own print_binary function.
for (int i = 31; i >= 0; i--) {
printf("%d", (n >> i) & 1);
}
I simply iterate over the 32 bits in the number n and shift the bits so that the i-th bit I want to print moves to the 0-th bit location. Then, I convert that new binary number to either a decimal 1 or 0 by performing a bitwise AND on it. See the example below.
n = 42 = ...00101010 (last 8 bits)
i=31: ...00101010 >> 31 = ...00000000 & 1 = 0
i=5: ...00101010 >> 5 = ...00000001 & 1 = 1
i=3: ...00101010 >> 3 = ...00000101 & 1 = 1
i=1: ...00101010 >> 1 = ...00010101 & 1 = 1
i=0: ...00101010 >> 0 = ...00101010 & 1 = 0
For decryption, I simply print the ASCII character for which the integer buffer corresponds.
printf("%c", (char) buf);