Corning Community College
CSCS1320 C/C++ Programming
======Project: Data Obfuscation - SECRET AGENT MESSAGES (sam0)======
=====Objective=====
To explore the implementation of caesar cipher encoding and decoding programs.
=====Background=====
A cipher is defined as "a secret or disguised way of writing; a code", and (as a verb): to put (a message) into secret writing; encode.
In the realm of secrecy (think elementary school secret agent), obfuscation is key. If we can remove direct accessibility to the message (encode), yet still preserve its intent, it can be transmit to a recipient who has the ability to retrieve the message (decode).
The caesar cipher (or shift cipher) is a relatively simple cipher, where each letter of the alphabet is shifted by a fixed amount, enabling a once legible message to appear unrecognizeable (at least directly).
Further background information can be found here:
* https://en.wikipedia.org/wiki/Caesar_cipher
There are two processes related to a lossless obfuscation of data:
* encoding - taking the readable text and making it obfuscated, according to a set process
* decoding - taking the obfuscated text and making it readable, by reversing the process
Please NOT: What we are doing is **encoding**, and NOT encrypting.
=====Program=====
You are to implement one program, which contains two fundamental modes of operation:
* **encode** functionality: takes plain text message as input (via **stdin**), along with a cipher key, and outputs the encoded (obfuscated) result
* key should be provided via command-line argument (or, if present, a file in the current directory called '**cipher.key**')
* **decode** functionality: takes the encoded (obfuscated) message (via **stdin**), along with a cipher key, and outputs the decoded (readable, plain text) result
* key should be provided via command-line argument (or, if present, a file in the current directory called '**cipher.key**')
The key should be a **signed char**, allowing for a cipher shift of -128 to +127 (your shift can be left or right, depending on the sign of the number).
The **encode** and **decode** functionality will be located in functions you declare and define, which your program's **main()** function calls upon determining the specified mode of operation.
Operating mode will be determined by the program's name:
* Naming your program **encode** will invoke the encoding functionality.
* Naming your program **decode** will invoke the decoding functionality.
* Mode auto-detection should work regardless of any prefixing path information (**./decode**, **/home/$USER/src/SEMESTER/DESIG/sam0/encode**, etc.)
* you may want to explore the **strtok(3)** or **basename(3)** functions to assist you, or write your own to obtain similar functionality.
Your program needs to:
* load the provided input (via **stdin**) into an array for processing (you may want to check for an EOF character to terminate input)
* assume a maximum input size of 4096 bytes
* use the **fgetc(3)** function instead of **fscanf(3)** for reading input from STDIN (do NOT use any **scanf()** or **gets()** related function, **ONLY fgetc(3)**).
* obtain the signed char key value from the command-line, if present, or read from the '**cipher.key**' file
* if neither command-line nor key file are available, display error and exit
* appropriately "shift" the alphabet according to the key (magnitude and direction and mode), storing the results in an array
* display the resultant string to STDOUT
* the cipher should work only on upper and lowercase letters of the alphabet. Any punctuation, number, whitespace, or other symbol should remain intact (knowing your ASCII table would be helpful).
* the encoding and decoding functionality needs to occur within declared/defined functions you create that are called from **main()** to perform the intended operation.
* As they will be performing operations on your array filled with the input data, you also need to make productive use of loops.
* all data needed by the function needs to be passed in by parameter! No global variables.
* The functions should return an integer containing the exact count of non-letters encountered (and therefore left unmodified from input to output). Your **main()** function needs to return this value when complete.
Your program should be a "one shot". It should only perform its intended operation and exit. No prompting for encode/decode, no "do you want to go again"... just a read from input, process, output, and exit with appropriate return value. They should conform to the execution examples found in this project.
When compiling, an additional constraint is added: compile with the **-Wall** and **--std=gnu18** flags.
====Sample execution: encode====
Via positive command-line key:
lab46:~/src/SEMESTER/DESIG/sam0$ ./encode 2
"hello"!!
"jgnnq"!!
emmbzwc
goodbye
^D
lab46:~/src/SEMESTER/DESIG/sam0$
**NOTE:** ^D indicated the CTRL-d sequence, which generates an EOF. That is the keypress you use to terminate the program; do NOT have your program display '^D' and exit on its own after one input, for there may be many.
Via negative command-line key:
lab46:~/src/SEMESTER/DESIG/sam0$ ./encode -3
hello, there...
ebiil, qebob...
^D
lab46:~/src/SEMESTER/DESIG/sam0$
//Without// command-line //nor// cipher.key file:
lab46:~/src/SEMESTER/DESIG/sam0$ ./encode
ERROR: key not found
lab46:~/src/SEMESTER/DESIG/sam0$
With **4** in the **cipher.key** file:
lab46:~/src/SEMESTER/DESIG/sam0$ echo "4" > cipher.key
lab46:~/src/SEMESTER/DESIG/sam0$ ./encode
hello there
lipps xlivi
^D
lab46:~/src/SEMESTER/DESIG/sam0$
Same thing, but saving the encoded text to a file:
lab46:~/src/SEMESTER/DESIG/sam0$ echo "4" > cipher.key
lab46:~/src/SEMESTER/DESIG/sam0$ ./encode <<< "hello there" > code.out
lab46:~/src/SEMESTER/DESIG/sam0$
With **4** in the **cipher.key** file, decoding previous message (redirected to **code.out**):
lab46:~/src/SEMESTER/DESIG/sam0$ ./decode < code.out
hello there
^D
lab46:~/src/SEMESTER/DESIG/sam0$
Note that when you decode, you should get the original message before it was encoded.
Via positive command-line key, decoding:
lab46:~/src/SEMESTER/DESIG/sam0$ ./decode 2
"jgnnq"!!
"hello"!!
^D
lab46:~/src/SEMESTER/DESIG/sam0$
You can also save typing, by providing your input via a //here string// (also a nice way to check for EOF):
lab46:~/src/SEMESTER/DESIG/sam0$ ./decode 2 <<< "jgnnq."
hello.
lab46:~/src/SEMESTER/DESIG/sam0$
=====Pseudocode=====
====encode====
Your encode may end up flowing something like the following:
MODULE ENCODE (RECEIVES MESSAGE AND KEY):
LOOP THROUGH EACH CHARACTER IN THE MESSAGE:
CHARACTER IS SET TO NUMERIC VALUE OF CHARACTER PLUS THE KEY
SHOULD THE CHARACTER EXCEED THE RANGE OF DISPLAYABLE CHARACTERS:
RESET CHARACTER TO START OF RANGE PLUS REMAINING OFFSET OF KEY
SHOULD THE CHARACTER GO BELOW THE RANGE OF DISPLAYABLE CHARACTERS:
RESET CHARACTER TO END OF RANGE MINUS REMAINING OFFSET OF KEY
SET MODIFIED CHARACTER TO RESULT MESSAGE
END LOOP
SEND BACK RESULT MESSAGE
END MODULE
====decode====
MODULE DECODE (RECEIVES MESSAGE AND KEY):
LOOP THROUGH EACH CHARACTER IN THE MESSAGE:
CHARACTER IS SET TO NUMERIC VALUE OF CHARACTER MINUS THE KEY
SHOULD THE CHARACTER EXCEED THE RANGE OF DISPLAYABLE CHARACTERS:
RESET CHARACTER TO START OF RANGE PLUS REMAINING OFFSET OF KEY
SHOULD THE CHARACTER GO BELOW THE RANGE OF DISPLAYABLE CHARACTERS:
RESET CHARACTER TO END OF RANGE MINUS REMAINING OFFSET OF KEY
SET MODIFIED CHARACTER TO RESULT MESSAGE
END LOOP
SEND BACK RESULT MESSAGE
END MODULE
=====Submission=====
To successfully complete this project, the following criteria must be met:
* Code must compile cleanly (no warnings or errors)
* Use the **-Wall** and **--std=gnu18** flags when compiling.
* Output must be correct, and resemble the form given in the sample output above.
* Code must be nicely and consistently indented (you may use the **indent** tool)
* Code must utilize the algorithm/approach presented above
* Code must be commented
* have a properly filled-out comment banner at the top
* have at least 20% of your program consist of **//**-style descriptive comments
* Track/version the source code in a repository
* Submit a copy of your source code to me using the **submit** tool.
To submit this program to me using the **submit** tool, run the following command at your lab46 prompt:
$ make submit
You should get some sort of confirmation indicating successful submission if all went according to plan. If not, check for typos and or locational mismatches.
=====Evaluation Criteria=====
What I will be looking for:
78:sam0:final tally of results (78/78)
*:sam0:sam0.c compiles cleanly, no compiler messages [13/13]
*:sam0:sam0.c implements only specified algorithm [13/13]
*:sam0:sam0.c code conforms to project specifications [13/13]
*:sam0:sam0.c code committed and pushed to repository [13/13]
*:sam0:sam0 runtime output conforms to specifications [26/26]
Additionally:
* Solutions not abiding by spirit of project will be subject to a 25% overall deduction
* Solutions not utilizing descriptive why and how comments will be subject to a 25% overall deduction
* Solutions not utilizing indentation to promote scope and clarity will be subject to a 25% overall deduction
* Solutions not organized and easy to read (assume a terminal at least 90 characters wide, 40 characters tall) are subject to a 25% overall deduction