Substitution

Implement a program that implements a substitution cipher, per the below.

$ ./substitution JTREKYAVOGDXPSNCUIZLFBMWHQ
plaintext:  HELLO
ciphertext: VKXXN

Background

In a substitution cipher, we “encrypt” (i.e., conceal in a reversible way) a message by replacing every letter with another letter. To do so, we use a key: in this case, a mapping of each of the letters of the alphabet to the letter it should correspond to when we encrypt it. To “decrypt” the message, the receiver of the message would need to know the key, so that they can reverse the process: translating the encrypt text (generally called ciphertext) back into the original message (generally called plaintext).

A key, for example, might be the string NQXPOMAFTRHLZGECYJIUWSKDVB. This 26-character key means that A (the first letter of the alphabet) should be converted into N (the first character of the key), B (the second letter of the alphabet) should be converted into Q (the second character of the key), and so forth.

A message like HELLO, then, would be encrypted as FOLLE, replacing each of the letters according to the mapping determined by the key.

Let’s write a program called substitution that enables you to encrypt messages using a substitution cipher. At the time the user executes the program, they should decide, by providing a command-line argument, on what the key should be in the secret message they’ll provide at runtime.

Here are a few examples of how the program might work. For example, if the user inputs a key of YTNSHKVEFXRBAUQZCLWDMIPGJO and a plaintext of HELLO:

$ ./substitution YTNSHKVEFXRBAUQZCLWDMIPGJO
plaintext:  HELLO
ciphertext: EHBBQ

Here’s how the program might work if the user provides a key of VCHPRZGJNTLSKFBDQWAXEUYMOI and a plaintext of hello, world:

$ ./substitution VCHPRZGJNTLSKFBDQWAXEUYMOI
plaintext:  hello, world
ciphertext: jrssb, ybwsp

Notice that neither the comma nor the space were substituted by the cipher. Only substitute alphabetical characters! Notice, too, that the case of the original message has been preserved. Lowercase letters remain lowercase, and uppercase letters remain uppercase.

Whether the characters in the key itself are uppercase or lowercase doesn’t matter. A key of VCHPRZGJNTLSKFBDQWAXEUYMOI is functionally identical to a key of vchprzgjntlskfbdqwaxeuymoi (as is, for that matter, VcHpRzGjNtLsKfBdQwAxEuYmOi).

And what if a user doesn’t provide a valid key?

$ ./substitution ABC
Key must contain 26 characters.

Or really doesn’t cooperate?

$ ./substitution
Usage: ./substitution key

Or even…

$ ./substitution 1 2 3
Usage: ./substitution key
Try It

To try out the staff’s implementation of this problem, execute

./substitution key

substituting a valid key in place of key, within this sandbox.

Specification

Instructions for Harvard College students
  • Head to GitHub and, after signing in, accept this assignment on GitHub Classroom.
  • After about a minute, refresh the page and click the link to visit your personal GitHub Classroom assignment page.
  • On the assignment page, click the green Code button and choose Open with Codespaces.
  • Cilck New codespace and then, if prompted, Create codespace.
  • Once your Codespace loads, click the + button in the bottom section of your window (next to the word “bash”). You should then see blue text appear that says /workspaces/substitution-USERNAME (where USERNAME is your GitHub username).
Instructions for non-Harvard College students

Create a new directory called substitution inside of your pset2 directory by executing

~/ $ mkdir ~/pset2/substitution

Create a new file called substitution.c inside your substitution directory.

Design and implement a program in substitution.c that encrypts messages using a substitution cipher.

  • Your program must accept a single command-line argument, the key to use for the substitution. The key itself should be case-insensitive, so whether any character in the key is uppercase or lowercase should not affect the behavior of your program.
  • If your program is executed without any command-line arguments or with more than one command-line argument, your program should print an error message of your choice (with printf) and return from main a value of 1 (which tends to signify an error) immediately.
  • If the key is invalid (as by not containing 26 characters, containing any character that is not an alphabetic character, or not containing each letter exactly once), your program should print an error message of your choice (with printf) and return from main a value of 1 immediately.
  • Your program must output plaintext: (without a newline) and then prompt the user for a string of plaintext (using get_string).
  • Your program must output ciphertext: (without a newline) followed by the plaintext’s corresponding ciphertext, with each alphabetical character in the plaintext substituted for the corresponding character in the ciphertext; non-alphabetical characters should be outputted unchanged.
  • Your program must preserve case: capitalized letters must remain capitalized letters; lowercase letters must remain lowercase letters.
  • After outputting ciphertext, you should print a newline. Your program should then exit by returning 0 from main.

Walkthrough

How to Test Your Code

Execute the below to evaluate the correctness of your code using check50. But be sure to compile and test it yourself as well!

check50 cs50/problems/2021/summer/substitution

Execute the below to evaluate the style of your code using style50.

style50 substitution.c

How to Submit

Instructions for Harvard College students

Harvard College students (those with an @college.harvard.edu email address) should submit this problem via GitHub, not via Gradescope.

In your Codespace, execute the below, replacing USERNAME with your actual GitHub username.

submit50 classroom50/substitution USERNAME
Instructions for non-Harvard College students
  1. Download your substitution.c file by control-clicking or right-clicking on the file in CS50 IDE’s file browser and choosing Download.
  2. Go to CS50’s Gradescope page.
  3. Click “Problem Set 2: Substitution”.
  4. Drag and drop your substitution.c file to the area that says “Drag & Drop”. Be sure it has the correct filename!
  5. Click “Upload”.

You should see a message that says “Problem Set 2: Substitution submitted successfully!” You won’t see a score just yet, but if you see the message then we’ve received your submission!