github linkedin vsco
← home

Encryption Challenge

5 Jun 2024 | Edited: 21 Mar 2025

Create a program that, when given both a file and a (integer) key, encrypts the file by adding together the ASCII number 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. At first, I stored encrypted messages in text files containing ASCII 1s and 0s. This approach was slow, so I eventually moved towards using actual binary files which sped up the program tremendously and made the algorithm much simpler. The code for this program is on GitHub.

Encryption

Integers are stored as 32-bit binary numbers. So, using binary files saved me the trouble of converting each calculated number to a 32-bit binary number. To encrypt a file, I read it character-by-character:

char buf[1]; // buf is each character
while (!feof(infile)) {
    fread(buf, sizeof(buf), 1, infile);
    ...
}

Then, I encrypt the character by calculating the ascii_code from the character’s ASCII number + the key + the index. The ASCII code will be converted to binary when written to the encrypted file:

int ascii_code = (int)*buf + KEY + i;
fwrite(&ascii_code, sizeof(ascii_code), 1 , outfile);

Decryption

Again, using binary files saved me a lot of trouble when decrypting. To decrypt files, I made my buffer an integer, which is a 32-bit binary number, so the program will read every 32 bits into the buffer from the binary file:

int buf;
while (!feof(infile)) {
    fread(&buf, sizeof(buf), 1, infile);
    ...
}

Then I do the reverse of encryption by subtracting each integer by the key and its index:

buf -= KEY + i;

Printing

The program accepts an input file using the -i flag and outputs to a file using the -o flag. Both of these flags are required. I also added an optional -v flag to print a verbose output of what the program was writing to the output file. This meant I had to use part of my original ASCII-based algorithm to print to the console during encryption. This algorithm iterates in reverse over a 32-length integer array:

int binary_num[32];
for (int j = 31; j >= 0; j--) {
    ...
}

If the ascii_code does not equal to 0, it will mod it by 2. When dividing a number by 2, there are only two possible remainders it can return, 1 or 0. Then it will set ascii_code to itself divided by 2:

if (ascii_code != 0) {
    binary_num[j] = ascii_code % 2;
    ascii_code /= 2;
}

So if the ascii_code was 12, the program will convert it to binary as follows:

12 mod 2 = 0    12/2 = 6
 6 mod 2 = 0    6/2 = 3
 3 mod 2 = 1    3/2 = 1
 1 mod 2 = 1    1/2 = 0

Result: 1100

If the ascii_code equals 0, meaning the entire number has been converted to binary, it will fill the remaining indices in the binary_num array with zeroes to ensure all 32 indices have a value so it will accurately represent the 32-bit integer that is being written to the encrypted file. Then the program iterates over the binary_num array, printing each index:

for (int j = 0; j < 32; j++) {
    printf("%d", binary_num[j]);
}

When printing during decryption, the program simply prints the ASCII character that the integer buffer corresponds to:

printf("%c", (char)buf);