BRIAN: In substitution, your task is going
to be to implement a substitution cipher where you'll encrypt or encipher
some plain text by taking every alphabetic character in that plain text
and replacing it with another character.
What might that actually look like?
Well, let's take a look at a sample key.
Here, we have the plain text letters of the alphabet
from A all the way through Z. And in a substitution cipher,
we're going to replace each of those plain text characters
with a cipher text character.
For example, here is a mapping that maps the plain text character
A to the letter J, maps the letter B to T, maps the letter C to R,
so on and so forth.
How do we actually use this inside of a cipher?
Well, if the plain text is the word hello, then using this substitution
cipher, we would end up with the cipher text VKXXN because H in plain text maps
to V in the cipher text.
E maps to K both of the Ls map to the letter X. And of course,
O maps to the letter N, which gives us that resulting cipher text.
Your task is going to be to write a program in C that is going to implement
such a substitution cipher.
How does the program work?
Well, you'll run the program by calling dot slash substitution followed
by a 26-character-long key that's going to describe how you're
going to map each of the alphabetic characters
into other alphabetic characters where here, the first character is what
we map A to, the second character is what we might B to, so on and so forth.
Your program should then prompt the user to type in some plain text.
And if the user types in ABC, for example,
then your program should output cipher text
followed by the enciphered version of that plain text-- in this case, J, T,
and then R. So if we were to call that same substitution
cipher passing in hello as the plain text, then the output is VKXXN.
Of course, your program should be able to support plain text that isn't just
uppercase characters.
So if we were to instead call dot slash substitution followed by the same key
and the plain text were hello in all lowercase letters,
then the output should still be vkxxn but the characters should be lowercase.
The case of the plain text should be preserved.
And if our plain text was a little more complicated, for example,
if we called dot slash substitution on the same key
but this time the plain text were this is CS50,
then this is what the cipher text would look like.
Notice in particular that the characters that
were originally uppercase in the plain text
are still uppercase in the cipher text, and the characters that
were originally lowercase in the plain text
are still lowercase in the cipher text.
Any character that isn't a letter, like the space
or the digits or the punctuation, those haven't been changed at all.
And they're the same in both the plain text and the cipher text.
In addition, the key that your program takes as a command line argument
should be case insensitive.
Here, for example, the key is all uppercase letters.
But the program should behave exactly the same
if, for example, the key were all lowercase letters
or if there was a mix of uppercase and lowercase letters inside of the key.
However, not every key that's provided as a command line argument
is necessarily going to be a valid substitution cipher.
So there's some additional work you'll need
to do in order to validate the key to make sure it is indeed valid.
For example, if a user were to call dot slash substitution
but not provide a key at all, then your program
should remind the user of how to use the program by calling dot slash
substitution followed by a key.
What else might count as an invalid key?
Well, if a user were to call dot slash substitution and provide a key that's
fewer than 26 characters, then we're not going
to know how to map every single alphabetic character
to another character.
So in this case, your program, rather than prompting the user
to type in any plain text should instead report
that the key must contain 26 characters and then
return with a status code of one to indicate an error.
What else might be considered an invalid key?
Well, if the user were to run dot slash substitution and then provide
this key, which is 26 characters but the last character
is the number two instead of an alphabetic character,
this key is not valid because in a valid substitution cipher,
every letter should be substituted for another letter.
So if any character in the key that is provided as a command line argument
is not an alphabetic character, then your program
should report that error, reporting to the user
that the key must only contain alphabetic characters
and then returning one, for example, to indicate
that there was, in fact, an error.
And finally, if the user were to run dot slash substitution and then provide
this key, where notice that the first character of the key
is the letter J and the last character of the key is also the letter J,
this too is not a valid substitution.
And your program should report to the user
that the key should not contain repeated characters,
and your program should, again, exit with a return code of one.
So in summary what do you need to do in this problem?
Well, you'll first need to get the key.
Then you'll need to validate the key to make sure
that it's a valid substitution.
Then you'll need to prompt the user to type in some plain text.
Then you'll need to encipher that plain text using your substitution key.
And then finally, you'll need to print out that cipher text.
How are you going to get the key?
Well, recall that the key is going to be provided as a command line argument.
The user is going to run your program by running dot slash substitution followed
by the key.
How do you extract that command line argument?
Well, you can structure your main function as something
like this, taking two arguments, one of which
is an int argc representing the number of command line arguments,
and one of which is an array of strings, argv, representing all of the command
line arguments that were provided.
Once you've collected the command line arguments,
the next step is going to be validating the key to make sure that it's valid.
And here, you should check the key length
to make sure that it is, in fact, 26 characters.
You should also check to make sure that there are no non-alphabetic characters
inside of the key, and you should also check for repeated characters
because every letter of the alphabet should appear once and only once
in the key, regardless of whether it's uppercase or lowercase.
After you've validated the key, then you can
start to prompt the user to type in some input by asking for plain text.
Here, you can use the function get_string,
declared in the CS50 library, as a way of getting input
from the user as a string.
After you've gotten the string, then you can encipher the text
where for each alphabetic character you'll need to determine,
based on the substitution cipher that you've collected as a command line
argument input, what character should this alphabetic character
map to, making sure to preserve case so that uppercase characters stay
uppercase and lowercase characters stay lowercase.
If there are any non-alphabetic characters like spaces or punctuation
or numbers, those characters should be left
as is and unchanged between the plain text and the cipher text.
Finally, after all of that, you should be
able to print out the cipher text to the user
so that they see the enciphered version of their original message.
You can test your code by running dot slash substitution followed
by a valid 26-character substitution key, then typing in some plain text
and making sure the cipher text is the result of substituting
all of the alphabetic characters for the characters
that are mapped to by the key.
My name is Brian, and this was substitution.