From Professor Harry Porter’s Fall 2015 CS201 course: External link
For each student we have encrypted a file containing a secret message. Your task is to create a program to decrypt the file and discover the secret message.
We are using a different encryption algorithm for each student so each student will create a unique decryption program. The encryption / decryption algorithm is based on the first 3 letters of your last name.
In this assignment, you are to implement the decryption algorithm associated with your username. The key to your decryption algorithm is the first three letters of your last name. We are getting your name from the PSU registration system. [ Vu, Hanh vuh ]
There are 3 stages to the decryption scheme. The first letter of your key determines the first stage. The second letter of your key determines the second stage. The third letter of your key determines the third stage.
For every 4 bytes of the file <c0,c1,c2,c3>
, implement the following based on the first letter of your key:
‘a’ to ‘d’: Swap bytes c0
and c3
.
‘e’ to ‘h’: Swap bytes c1
and c2
.
‘i’ to ‘l’: Swap bytes c0
and c2
.
‘m’ to ‘p’: Swap bytes c1
and c3
.
‘q’ to ‘t’: Swap bytes c2
and c3
.
‘u’ to ‘z’: Swap bytes c0
and c1
.
For every byte of the file with bits <b7,b6,b5,b4,b3,b2,b1,b0>
, implement the following based on the second letter of your key:
‘a’ to ‘d’: Swap bits b7
and b1
, Swap bits b6
and b0
.
‘e’ to ‘h’: Swap bits b5
and b3
, Swap bits b4
and b2
.
‘i’ to ‘l’: Swap bits b7
and b3
, Swap bits b6
and b2
.
‘m’ to ‘p’: Swap bits b5
and b1
, Swap bits b4
and b0
.
‘q’ to ‘t’: Swap bits b7
and b5
, Swap bits b6
and b4
.
‘u’ to ‘z’: Swap bits b3
and b1
, Swap bits b2
and b0
.
For every 4 bytes of the file <c0,c1,c2,c3>
, implement the following based on the third letter of your key, <k3>
:
‘a’ to ‘d’: XOR
bytes c0
and c3
with k3
.
‘e’ to ‘h’: XOR
bytes c1
and c2
with k3
.
‘i’ to ‘l’: XOR
bytes c0
and c2
with k3
.
‘m’ to ‘p’: XOR
bytes c1
and c3
with k3
.
‘q’ to ‘t’: XOR
bytes c2
and c3
with k3
.
‘u’ to ‘z’: XOR
bytes c1
and c0
with k3
.
If the file size is not evenly divisible by 4 then, for the bytes at the end of the file that are not in a complete 4 byte block, the first and third stages are not to be applied.
Your program should take exactly one command line argument: the name of the file to decrypt. It should print the decrypted contents to stdout
.
Use argv
to obtain the filename.
You may use fopen
, fseek
, ftell
, malloc/calloc
, fread
, and fclose
to read the file into a buffer in memory.
Do not use the string libraries since NULL
bytes can and will be generated as part of the encryption/decryption
process.
The utility command “xxd” will print the contents of a file in hexadecimal. For example:
xxd filename
To see the file in binary:
xxd –b filename
(You can also useod –x
orhexdump
, but watch out;od
may perform byte reordering.)
For the second stage, the bit shift operator and bit masks are recommended for implementing the swap.
Here is the ciphertext above dumped out in hex bytes within my program. Note the byte ordering compared to the
output of od -x
:
Because my last name is “Porter”, in the first stage, I implement the corresponding algorithm for ‘p’, which is
swap bytes c1 and c3 in each 4 byte block. After, the first stage, this is the result in hex bytes:
For the second stage, I implement the corresponding algorithm for ‘o’, which is to swap bits b5 with b1 and b4 with b0 in each byte. After the second stage, this is the result in hex bytes:
Finally, for the third stage, I implement the corresponding algorithm for ‘r’, which is to XOR bytes c2 and c3 with ‘r’ (0x72) in each 4 byte block. After the third stage, this is the result in hex bytes:
When these bytes are output as a string, it outputs
Your program will be compiled with this command on the PSU linux lab machines:
Your program should work correctly. Therefore, your grade will be based on its simplicity, clarity, and efficiency.
Your program should handle all conditions and print reasonable error messages if it is not used correctly. All error output should go to stderr
. Nothing should go to stdout
except the decrypted output.
It seems likely that you can develop and test the program on your own computer and it will run identically on the PSU Linux machines, but it is up to you to make sure it runs correctly on the PSU Linux machines.