ECE 209 Program 1: cipher
Fall 2020
Due Friday, Sept 4 @ 11:59pm
This programming assignment must be completed individually. Do not share your code with or receive code from any other student. Evidence of copying or other unauthorized collaboration will be investigated as a potential academic integrity violation. The minimum penalty for cheating on a programming assignment is a grade of -100 on the assignment. If you are tempted to copy because you’re running late, or don’t know what you’re doing, you will be better off missing the assignment and taking a zero. Providing your code to someone is cheating, just as much as copying someone else’s work.
DO NOT copy code from the Internet, or use programs found online or in textbooks as a “starting point” for your code. Your job is to design and write this program from scratch, on your own. Evidence of using external code from any source will be investigated as a potential academic integrity violation.
This program uses a simple “Caesar cipher” to encrypt/decrypt a text string. The learning objectives of the program are:
• Write a complete C program.
• Use loops and conditional statements.
• Use array indexing (optional).
• Use printf and scanf to perform I/O.
Background
Encryption has long been used to communicate messages that are intended to be secret. With a good encryption scheme, only someone who knows the key can decrypt the secret message into readable text.
The “Caesar cipher” is a simple substitution cipher, in which each letter is replaced by shifting a certain number of positions in the alphabet. The key is the number of positions to shift. For example. if the key is 5, then the letter ‘A’ is replaced by the letter ‘F’ (five character later). Julius Caesar is known to have used such an encryption code, but it was likely us use well before his time.
Such an encryption scheme can be easily broken today, so it provides almost no actual security. But it’s an interesting programming problem.
Problem Description
For our cipher, we will encrypt/decrypt both letters and digits, but all other characters in the input text will be ignored. We extend the 26-character alphabet into 36 characters by appending the digit characters to the end:
ABCD…XYZ0123456789
1
As a result, shifting the character ‘Z’ by one to the right results in the character ‘0’. If shifting takes you beyond the end of the character list, you “wrap around” to the beginning of the sequence. For example, shifting ‘8’ by 3 results in ‘B’.
Mathematically, we can do this by assigning an index to each character in the sequence. The key will be a number between 1 and 35. Encryption is performed by (1) finding the index of the character, (2) use modulo-36 addition to add the key, and (3) determining which character corresponds to the new index.
Decryption is the same, except we subtract the key, again using modulo-36 arithmetic. If the result of the subtraction is negative, add 36. Alternatively, you can use the fact that subtracting k is the same as adding (36 – k).
The encryption program will skip over any non-alphanumeric character, including space, linefeed, and any punctuation. The end of the input will be denoted with two hash symbols: ##. The output will be printed in upper-case only, in groups of four letters, with up to five groups per line. (This style of grouping is common in cryptography, to make the output text easier to read/transcribe/interpret.)
Here’s an example run of the program, with the user choosing encryption with key = 6. User input is shown in bold.
Enter mode — encrypt (e) or decrypt (d): e Enter key (1-35): 6
Enter text, ending with ##:
Four score and seven years ago…##
LU0X YIUX KGTJ YK1K T4KG
XYGM U
If we feed the encrypted text (known as ciphertext) into the program to decrypt with the same key, we should get the original input. Below, I have removed the spaces and the linefeeds from the encrypted text to emphasize that these are determined by the output, not by the input.
Enter mode — encrypt (e) or decrypt (d): d Enter key (1-35): 6
Enter text, ending with ##: LU0XYIUXKGTJYK1KT4KGXYGMU##
FOUR SCOR EAND SEVE NYEA
RSAG O
Note that the spaces and the periods from the original text were lost during the encryption operation, so they don’t appear in the recovered text after decryption. We’ve also lost all distinction between lower- case and upper-case.
Program Specification
The entire program must be written in a single source code file, named main.c. A preliminary version of this file is provided for you. It already includes the user interface code that gets the mode and key
2
from the user, and prints the prompt for the input text. See the “Developing…” section below for instructions on how to get this file into your CLion project.
Your program will be tested with a variety of input strings. Each string will check the output, and your output must exactly match the specification in order pass the test. There will be no partial credit for a test; either your code passes or it doesn’t. If a test fails, figure out why and fix it.
Input specification:
• The input text can contain any type of character, including linefeeds. Any non-alphanumeric character will be ignored.
• Each input character will be processed until the terminating sequence ## is detected.
• The terminating sequence ## will end the processing of input. If any characters appear after that sequence, they will not be processed. There must be no space between the # characters in the terminating sequence.
Output
specification:
• Output must be alphanumeric characters only, and all letters must be upper-case.
• Output characters must be in groups of four. After each of the first four complete groups on a
line, a space must be printed. After the fifth complete group on a line, a linefeed must be printed instead of a space.
• A linefeed character must be printed at the end of the output text. Implementation
Do not try to read all the input as a string. Do not try to buffer the output as a string and then print it at the end. We have not covered how to do this, and it is not required or expected for this program. Process each character, one at a time, for both input and output.
If your input string has linefeeds, this may result in mixing up the input and output characters the console on some platforms. This might be annoying, but it’s fine. The ZyBook tests will separate the output characters from the input characters properly, so the way it prints on the screen will not cause the tests to fail.
Printing output characters in groups of four does not mean that you have to create a four-character string. (Again, we haven’t talked about this, so you should not expect that it’s necessary.) Print each output character as it is created; keep track of how many characters have been printed, and add the space or linefeed if needed.
The following functions from ctype.h may be helpful during your implementation. For more info: https://en.cppreference.com/w/c/string/byte
isalnum(c) — returns a non-zero value if character c is alphanumeric isdigit(c) — returns a non-zero value if character c is a decimal digit islower(c) — returns a non-zero value if character c is a lower-case letter isupper(c) — returns a non-zero value if character c is an upper-case letter toupper(c) — converts character c to uppercase
Note: toupper() returns an integer value, not a char. If you assign to a char, you may get a warning or an editor hint in CLion. This can be ignored.
3
You may use an array during the encryption/decryption process. This can make your code a little simpler, but it’s not required. Each of the following steps can be done using arithmetic operators:
1. Find index of character (after converting to upper-case or digit).
2. Add or subtract key, depending on mode, using modulo-36 arithmetic.
3. Find character that corresponds to the new index computed in step 2.
Use integer math only, not floating-point math. Remember that a character can be treated as a small integer, so you can use arithmetic operators on them.
Developing and Submitting the Program
You will submit this code as a zyBook lab, but you will develop the program outside of the zyBook. It is expected that you will use CLion, but you are free to use whatever development environment that you want.
1. In CLion, create a new project. Specify a C Executable, and use the C11 standard. Name the project whatever you like, but I recommend something meaningful like “prog1” or “cipher”. This will create a directory in the place where your CLion projects are kept. Exit CLion.
2. Go to Chapter 13 in the zyBook, and look for a lab in the Programming Assignments chapter titled: Fall 2020, Program 1: cipher.
3. Download the main.c file provided for you, and overwrite the main.c file in the CLion project that you created in Step 1.
4. Now use CLion to complete the program, using the editor, compiler, and debugger to meet the program specifications.
5. When you are ready, upload your main.c file to the zyBook assignment and submit. This will run the tests.
If some tests fail, go back to Step 4 and work on your program some more. The input for the failed tests will give you some idea of what’s not correct, but use the debugger to figure out what’s happening with your implementation.
Several iterations of Steps 4 and 5 might be necessary. In fact, it’s a reasonable strategy to write a program that only passes the first test (or some tests), then improve it to pass the next test, etc. (This even has a fancy name: test-driven development.)
There is no limit to the number of times you can submit. Each submission will overwrite the earlier ones, so make sure that your new code does not break tests that passed earlier.
Hints and Suggestions
• Don’t overcomplicate the program. Do not use anything that we have not covered in class. (For example, don’t try to use pointers or string library functions.)
• Work incrementally. Get one part of the code working, and then move to the next. For example, you might ignore the key and just work on ignoring input characters and printing output characters properly. Then you might try encryption. Then get decryption to work.
• For compiler errors, look at the source code statement mentioned in the error. Try to figure out what the error is telling you. Try to fix the first error first, and then recompile. Sometimes,
4
fixing the first error will make all the other errors go away. (Because the compiler got confused after the first error.)
• Use a source-level debugger to step through the program if the program behavior is not correct. If you are using CLion on your own computer, the debugger is integrated with the editor and compiler, so there’s no excuse for not using it.
• For general questions or clarifications, use Piazza, so that other students can see your question and the answer. For code-specific questions, post a private message to Piazza and attach your code as a file. (Do not copy and paste!)
Administrative Info
Updates or clarifications on Piazza:
Any corrections or clarifications to this program spec will be posted on Piazza. It is important that you read these postings, so that your program will match the updated specification.
What to turn in:
• Submit your main.c file to the zyLab assignment in 13.1, “Fall 2020, Program 1: cipher”. Grading criteria:
20 points: 10 points:
30 points:
20 points: 20 points:
Program submitted on time. As long as you’ve made some effort, and do not just submit the template file, you will get these points.
Proper coding style, comments, and headers. No global variables. No goto. See the Programming Assignments section on Moodle for more style guidelines. (You will not get these points if you only submit trivial code.)
Encrypting with a key of zero. These tests make sure that input and output characters are processed correctly (skipping characters, output in groups of four, etc.)
Encryption tests. Decryption tests.
NOTE: The ZyBook tests will only total 70 points. The first 30 points will be assigned manually by the grader.
NOTE: Points may be deducted for errors, even if all of the zyBook tests pass. This will be rare, but it may happen if it is obvious to the grader that the program is written specifically to pass the specific tests, and would not pass other similar tests.
Example: If the program only looks for the character ‘h’ at the end of a word, instead of any consonant, because that’s the only condition tested, then points will be deducted.
5