Home Page > > Details

COMPSCI 354 001 DHH

 ! SU20 COMPSCI 354 001 DHH Assignments P2 Enigma Machine

P2 Enigma Machine
Due Monday by 11:59pm Points 100 Submitting a file upload
Available Jun 28 at 12am - Jul 31 at 11:59pm about 1 month
Submit Assignment
Project 2: Enigma Machine
Corrections and Additions
None so far.
Files
1. enigma-machine-template.c
Learning Goals
1. Learn how to write a C program that follows the given specifications.
2. Learn how functions improve code by making it modular and task oriented.
3. Practice calling functions from different functions.
4. Practice passing arguments to functions.
5. Practice returning values from functions.
6. Develop code using one-dimensional and two-dimensional arrays.
7. Learn to write code that follows the commenting and the style guidelines. Style_Guide.pdf
Logistics
1. All work for this assignment is to be done on one of the UW CS department's instructional Unix/Linux machines.
2. All assignments in this course will be graded only on CS departmental machines (e.g., royal-01.cs.wisc.edu) running
Linux Operating System. It is your responsibility to make sure that your code runs on these machines correctly.
General Advice
1. If you are not using the CS departmental machines with Linux Operating System and would like to code using your
laptop then:
2. Please DON’T use an Integrated Development Environment (IDE) for learning to code in C. It’ll hide many of the low￾level details from you. You can become a good C programmer only if you understand all these low-level details.
3. Avoid using Windows Operating System for writing C code since the compiler that we’ll use for grading your
assignments is gcc (GNU C Compiler) which is a Unix/Linux based C compiler.
4. If you still insist on using a computer which already has a Windows OS, then you should have a virtual machine
(VMware or Virtualbox) to run a Linux OS. You’ll also need a compiler like MinGW or Cygwin (which contains tools like
gcc) installed on your Windows machine. To be honest connecting to the lab Linux machines is easier than getting those
software packages installed correctly.
Questions
1. If you have a question, please consider these options in order.
2. Post your question on Piazza and make it public for general questions. Feel free to post problem solving strategies, but
do not post code publicly.
3. If you need to post code, then make the post private. We will in general not help debug your code for syntax errors. We
will however explain cryptic compiler error messages. Please post both the code segment generating the error and a
screenshot of the cryptic error message.
4. Email your TA. For project 1, If you last name begins with A-L contact Yien at yien@cs.wisc.edu. If you last name begins
with M-Z contact Hannah at hstrohm@wisc.edu. Mike at mdoescher@wisc.edu.
Debugging advice
1. Write your code in very small sections at a time and verify that it compiles before continuing.
2. Fix the compiler error messages from the top down. The first error may cause other compiler error messages to
generate from correct code later in your file. So, scroll up and address the top error message first.
3. Ask questions about cryptic error messages. Post a screenshot of the error message on Piazza as a public post if you do
not need to share any code. Post privately if you do need to share your code.
Encryption and Decryption Using a Simple Enigma Machine
Enigma machine uses so called rotors to encrypt messages. Inside the skeleton code for enigma.c (given above in Files),
there is an array of strings called ROTOR_CONSTANTS that stores 9 rotors. For our project, rotor at position 0 is an
identity rotor. It is basically a string with original English alphabets in the correct order. Rotor 0 is given to help you better
see how the encryption and decryption processes occur. You cannot really use this rotor to encrypt messages since the
original message will not change. 
Rotors at positions 1 - 8 of the array ROTORS are strings with the letters of the alphabet appearing in various order. For
example, the rotors 0 to 3 are shown below.
Rotor 0 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
Rotor 1 - EKMFLGDQVZNTOWYHXUSPAIBRCJ
Rotor 2 - AJDKSIRUXBLHWTMCQGZNPYFVOE
Rotor 3 - BDFHJLCPRTXVZNYEIWGAKMUSQO
How to use rotors to encrypt messages? 
Encryption using one rotor
Let’s consider this example:
Message to be encrypted: JAVA
Rotor to use: 1
Number of rotations: 0
Encrypted message: ZEIE
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z -> rotor 0
E K M F L G D Q V Z N T O W Y H X U S P A I B R C J -> rotor 1
The position of J in the original alphabet is 9. Therefore, Enigma finds the letter at position 9 on the rotor 1 which is Z. The
position of A in the original alphabet is 0. Therefore, Enigma finds the letter at position 0 on the rotor 1 which is E, etc. This
is how the message “JAVA” has been encrypted to “ZEIE” using the rotor 1 (without performing any rotations).
Encryption using several rotors
Let’s consider this example:
Message to be encrypted: JAVA
Rotors to use: 1 2 4
Number of rotations: 0
Encrypted message: PTMT
The rotors 1, 2, and 4 that are used for encryption are shown below:
====================================================
ROTORS 1, 2, 4
====================================================
E K M F L G D Q V Z N T O W Y H X U S P A I B R C J -> rotor 1
A J D K S I R U X B L H W T M C Q G Z N P Y F V O E -> rotor 2
E S O V P Z J A Y Q U I R H X L N F T G K D C M W B -> rotor 4
----------------------------------------------------
Round 1:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z -> rotor 0
E K M F L G D Q V Z N T O W Y H X U S P A I B R C J -> rotor 1 
(result is ZEIE after using rotor 1 for encryption)
Round 2:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z -> rotor 0
A J D K S I R U X B L H W T M C Q G Z N P Y F V O E -> rotor 2
(result is ESXS after using rotor 2 for encryption)
Round 3:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z -> rotor 0
E S O V P Z J A Y Q U I R H X L N F T G K D C M W B -> rotor 4
(result is PTMT after using rotor 4 for encryption)
Encryption using several rotors is done in the same way as encryption using one rotor, however there will be several
rounds of encryption taking place. Once you get the message encrypted by rotor #1 which is ZEIE in our case, you pass it to
the next rotor, rotor #2. Encrypted message of the rotor #2 is passed to the next rotor #4. Thus, the last encrypted
message that comes out of rotor #4 is our final output PTMT.
Decryption in Enigma
In order to decrypt the message PTMT back to JAVA, the order of the rotors to be used should be reversed. Since we used
rotors 1, 2 and 4 (in this same order) to encrypt our message JAVA, in order to decrypt it we should use the same rotors in
the reverse order. i.e. 4, 2 and then 1. 
Message to be decrypted: PTMT
Rotors to use: 4 2 1
Number of rotations: 0
Decrypted message: JAVA
The procedure here is that you take rotor 4 and find the letters PTMT on this rotor and most importantly you extract the
position of these letters on the rotor. Then, you use these positions to generate the first decrypted message by looking at
which letter appears on these positions in the original alphabet, i.e. rotor 0. This way you get your first encrypted message
that is ESXS. Then, again you take rotor 2 and find the positions of the letters ESXS on rotor 2. By looking what letters
appear on these positions in the original alphabet you build a second decrypted message which is ZEIE. Last round gives
you the final output that is JAVA when you use rotor 1 to decrypt ZEIE.
Rotating the rotors in Enigma
While performing encryption or decryption on the message, we enter some number from 0 to 25 as a number of rotations.
Number of rotations is simply the number of how many times you want to move the rotor values to the right (each row).
For example, for the rotor 1 if you want to perform rotation equal to 3, then
 Rotor 1: E K M F L G D Q V Z N T O W Y H X U S P A I B R C J
 Rotated rotor 1 by 3: R C J E K M F L G D Q V Z N T O W Y H X U S P A I B
The effects of rotating the rotors 1, 2, and 4 THREE times is shown below:
====================================================
ROTORS 1, 2, 4 BEFORE ROTATION
====================================================
E K M F L G D Q V Z N T O W Y H X U S P A I B R C J -> rotor 1
A J D K S I R U X B L H W T M C Q G Z N P Y F V O E -> rotor 2
E S O V P Z J A Y Q U I R H X L N F T G K D C M W B -> rotor 4
----------------------------------------------------
====================================================
ROTORS 1, 2, 4 AFTER ROTATING THEM 3 TIMES
====================================================
R C J E K M F L G D Q V Z N T O W Y H X U S P A I B -> rotor 1
V O E A J D K S I R U X B L H W T M C Q G Z N P Y F -> rotor 2
M W B E S O V P Z J A Y Q U I R H X L N F T G K D C -> rotor 4
----------------------------------------------------
After completing a rotation for the rotor configurations array, encryption and decryption procedures take place in the
same way as described before. When you want to encrypt a message with a particular number of rotations (for the rotors),
then while decrypting that message back to it’s original message, you need to use the same value for the number of
rotations (for the rotors) but the rotor indices should be in the reverse order. This will be more clear from the example
given below.
Message to be encrypted: JAVA
Rotors to use: 1 2 4
Number of rotations: 3
Encrypted message: MQBQ
Round 1:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z -> rotor 0
R C J E K M F L G D Q V Z N T O W Y H X U S P A I B -> rotor 1 (rotated)
(result is DRSR after using rotor 1 (rotated 3 times) for encryption)
Round 2:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z -> rotor 0
V O E A J D K S I R U X B L H W T M C Q G Z N P Y F -> rotor 2 (rotated)
(result is AMCM after using rotor 2 (rotated 3 times) for encryption)
Round 3:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z -> rotor 0
M W B E S O V P Z J A Y Q U I R H X L N F T G K D C -> rotor 4 (rotated)
(result is MQBQ after using rotor 4 (rotated 3 times) for encryption)
Note that even though we have used the same three rotors (rotors 1, 2, and 4) as used in section 4.2.2 for encrypting the
message JAVA we have obtained a completely different encrypted message since all the three rotors have been rotated 3
times before we performed the encryption.
The following configuration is to be used if we want to decrypt the message MQBQ back to JAVA:
Message to be decrypted: MQBQ
Rotors to use: 4 2 1
Number of rotations: 3
Decrypted message: JAVA
Part 0: General Program Information
YOU SHOULD NOT:
1. Modify the parameters of any functions in enigma.c
2. Modify the return type of any functions in enigma.c
3. Modify the main function in enigma.c
You will have to make changes to the enigma-machine-template.c file (remember it's easy to rename your file) and you
have to fill in all the blank parts in this code with the help of comments before the function as well as in the body. You are
allowed to create other functions that you find to be helpful. There are already two there that you can use:
int string_length(char * str)
returns the length of a character array, and 
int check_digit(int num)
returns true if the number provided is an integer and false if it does not.
At the top of enigma-machine-template.c, there are global variables declared and initialized. You have to use those
variables to print necessary messages to the user of the machine and in order to make sure your output matches exactly
the expected output. For example, very first message you need to print is the welcome message which is stored in the
String named WELCOME_MSG in Enigma.java.
Willkommen auf der Enigma-Maschine!
that's "Welcome to the Enigma Machine" in German.
Part 1: Validate User Input
int validate_options(char *options) { }
This function is the first one called from the main function. It should check whether the value entered by the user is an
integer, if it is an integer, then check whether it is equal to 1, 2 or 3. If it is one of these numbers, then return the number
itself (1, 2 or 3). If it is not one of these numbers, then the function returns -1 for invalid input. If the user didn’t enter an
integer, but instead entered a String, then also this function should return -1 showing that input is invalid. 
The meaning of the menu options:
1 - user wants to exit the program and stop Enigma
2 - user wants to encrypt some message
3 - user wants to decrypt some message
This will be returned to the main function, which will respond to the command returned by this function.
int * parse_rotor_indices(char *rotor_indices_line){ }
This function is called from the main function if the user chooses to encrypt or decrypt some message. The user is allowed
to enter four integers from 0 to 8 (inclusive) which are rotor indices. The maximum number of rotors the user can type is 4.
This function should preform the following checks:
If the user doesn’t enter anything, this function prints the message in the String NO_ROTORS_MSG and should return
null.
If user enters more than 4 integers, print the message in the String MORE_THAN_ALLOWED and return null. 
If user enters integers not in the range from 0 to 8 or something other than integers, then this function should print the
message in the String INVALID_ROTOR_MSG and return null. 
The same rotor cannot be used twice in a row in the rotor configuration. If the rotors entered are 1 2 2, that is invalid,
but if the rotors are entered 2 1 2, that is allowed. In case duplicate rotor numbers are entered in a row, then this
function should print the message DUP_ROTORS_MSG and should return null. 
If user enters input correctly, then this function returns an array of integers with the indices of the rotors entered by
the user. For example, if the input is 1 3 4, then the integer array will be [1, 3, 4]. 
Because you are providing output in this section, make sure you are following the directions carefully. All print statements
should be printed like this:
printf("%s", MESSAGE_NAME);
without a '\n'.
Also, the return array is initialized for you with -1 values. Make sure all unused positions in the array are set to -1. If this
function returns null, then your program will ask the user to enter the input again.
int validate_num_rotations(char *num_rotations_input){ }
This function is written for you. It validates the number of rotations entered by the user.
Part 2: Configure the Enigma Machine
int** set_up_rotors(int *rotor_indices) { }
This function is called from the main function when the user enters a valid rotor configuration, and is passed the array from
the previous function. It creates a 2D array with the number of rows equal to the number of rotor indices in the 1D array
passed to it and the number of columns equal to the rotor length (equal to 26). For example, if 1D array is [1, 3, 4], the 2D
array that you’ll be creating inside this function will contain 3 rows and the values for each row will be the letters in each
rotor denoted using the position of those letters in the English alphabet. A is at position 0, B is at position 1, and Z is at
position 25.
For example, the rotor 1 which has the contents "EKMFLGDQVZNTOWYHXUSPAIBRCJ" will be represented as:
[4 10 12 5 11 6 3 16 21 25 13 19 14 22 24 7 23 20 18 15 0 8 1 17 2 9]
E is represented as 4, K is represented as 10, and so on.
This is how the 2D array should look like for this example where the rotor configuration is [1, 3, 4].
[4 10 12 5 11 6 3 16 21 25 13 19 14 22 24 7 23 20 18 15 0 8 1 17 2 9]
[1 3 5 7 9 11 2 15 17 19 23 21 25 13 24 4 8 22 6 0 10 12 20 18 16 14]
[4 18 14 21 15 25 9 0 24 16 20 8 17 7 23 11 13 5 19 6 10 3 2 12 22 1]
void display_rotor_configuration(int** rotor_config, 
 int num_rows, int num_cols) { } 
This function is written for you. It displays the rotor configuration created in the previous function. After this, the function
int validate_num_rotations(char *num_rotations_input){ }
is called. It is also written for you, and is listed in the Validate User Input section. 
int** rotate_rotors(int num_of_rotations, int** rotor_Set, 
 int num_rows, int num_cols) { }
This function accepts the integer number of rotations, 2D array of rotors that needs to be rotated by this number and also
the number of rows and columns in this 2D array of rotors. It should return a 2D array of rotor that is rotated. If number of
rotations equals to 0, then the original 2D array should be returned without any changes. If the number of rotations is
between 1 and 25, then each row of the 2D array should be rotated to the right by this number.
After rotating the 2D array, your program should print the message contained in the String ROTOR_AFTER_ROTATION
and then should call the function
display_rotor_configuration() { }
while passing to it the rotated 2D array and its dimensions in order to print it and display the result of the rotation. Take a
look at the Rotating Rotors in Enigma section for an example of a rotation.
Part 3: Encryption and Decryption
char * encrypt(char *message, int **rotor_Set, 
 int num_rows, int num_cols) { }
char * decrypt(char *message, int** rotor_Set, 
 int num_rows, int num_cols) { }
These functions accept a string message that needs to be encrypted or decrypted and the 2D array of rotor configurations
that should be used for encryption / decryption. Before working with an input string, both of these functions should
change it to all uppercase characters. For example, if the input message was “all is well”, these functions should change it to
“ALL IS WELL” before encryption or decryption is done.
Each of these functions returns a String. The function encrypt() returns the encrypted form of the input message. The
function decrypt() returns the decrypted form of the input message. Messages that are returned from these functions are
always UPPERCASE strings. Input messages can contain spaces, but they are not translated to anything, so they remain as
they are in the output. Only the lowercase (a - z) or uppercase letters (A - Z) should be translated. Finally, the encrypted or
the decrypted message will be printed to the console.
Testing
Please make sure that your program prints the output exactly as the template file, because we use automatic scripts to
test your code. 
Part 4: Turning in your work
From a terminal on your home computer use the following command to download your work to your home computer:
prompt> scp username@best-linux.cs.wisc.edu:private/CS354/Project2/enigma-machine.c ./enigma-machine.c
or on Windows use pscp:
prompt> pscp username@best-linux.cs.wisc.edu:private/CS354/Project2/enigma-machine.c ./enigma-machine.c
Note that if you open the file on your home computer and then resave it may change the line ending symbols. Linux uses
one bit pattern to represent end of line characters and Windows uses another. It would be best to make all changes on the
CSL machines.
Upload your assignment to Canvas.
Sample Output
Only one rotor without rotation
OPTIONS
2 : encrypt a message
 
Contact Us - Email:99515681@qq.com    WeChat:codinghelp
Programming Assignment Help!