>> ZAMYLA: Let's tackle Caesar.
In Caesar, we allow the user to encode a secret message.
So let's dive right in and look at our to-dos for this problem.
So first, we get the key from the user.
Then we get the plaintext that they want to encode.
After that, we encipher it for them, and finally we print their ciphertext.
>> So let's start with an example.
Say you wanted to encode the entire alphabet with a key of two.
Well, your entire alphabet would just be shifted to letters.
So A would encode to C, B to D, C to E, so on and so forth,
until you get to X, which encodes to Z or zed, depending on where you're from.
Then Y would then shift all the way, wrap around the alphabet to get to A,
and then finally the last letter of the alphabet, Z, zed, would encode to B.
>> You got that?
Let's look at some examples.
The first example here is very similar to what we just explained above.
So if I encode some section of the alphabet, A through L, by a key of two,
then I just get my entire alphabet shifted two letters.
>> Then, in my next example, the key is still two,
so you should still know which letters to expect.
But here it's a phrase.
This is CS50.
So you'll notice that I preserve the case of my letters,
so any upper case letters are also upper case letters in the ciphertext.
And any lowercase letters in the plaintext
are also lowercase letters in the ciphertext.
But I keep the letters and any exclamation marks
or any other punctuation the same.
>> So now that we have a sense for how the program works,
feel free to go run some more examples of your own, if you wish.
Let's start with getting the key from the user.
Traditionally, with other problems, we've
been accustomed to getting any numbers that we
need by prompting the user with the function getint.
But this time we're actually going to use the command line argument
and a new function called atoi.
>> When you run the main program in C, then it
takes in two parameters-- int argc, which
is the number of arguments passed in, and then
argv, an array of strings which contains the list of all of the arguments
passed.
You don't explicitly have to declare these variables.
They're computed for you by the compiler.
Correct usage for this would be for argc to be two in this case,
because the user has to pass in the call to the program, ./caesar,
and then the key, whatever number they wish.
So that means that argc must be two in order for a valid use of Caesar
to be executed.
>> So let's look at an example.
Say I've already written and compiled a program called blastoff.
So if I ran in the command line ./blastoff Team Rocket, well, then,
argc would be three because I passed in three distinct arguments.
Then argv would look like this.
It's an array, and it would contain each of the three strings.
./blastoff in the first index, team in the next, and rocket in the last.
>> Let's talk about arrays for a sec.
Arrays are data structures that hold multiple values of the same type.
This can come in handy when we have lists of integers or strings.
Just remember they have to be the same type.
In computer science, we love counting from zero,
so remember that arrays are also zero-indexed.
So the first element of my array is going to be at index zero.
So in this case, when I have an array of length four,
then the last index of the last element of my array
is actually going to be at index three, not four.
Because remember, we start counting at zero.
>> Here's an example of how you might create an array of your own.
So say I wanted to store my three favorite dog names.
Then I would create an array of strings.
So I would declare the type, string, and then put the name of the array, dogs,
and then in those square brackets put the size
of the array-- in this case, three.
>> So my first entry is going to be dogs at index zero,
and that's going to be Milo.
Then dogs at index one is going to be goofy,
darling Mochi, and then the last entry, the third entry at index two,
is going to be cute, sweet Elphie.
You'll notice that the format for filling in this array
is very much like how you might declare any other variable where
you have the variable name followed by the value that you want stored in it.
The only difference in this case is that you
have to remember to put the index of the value in square brackets.
And there we have our three favorite dogs.
>> But alas, it's time to get back to Caesar.
Remember that correct usage for the user is going to be passing in not only
the name of the program ./caesar, but also the key that they want to shift
their plaintext by.
So that means that argc must be two.
They must pass in two-- no more, no less than two command line arguments.
>> Now, what about argv?
Well, we already know that the array is going to be of length two,
but what's contained in each element?
Well, the first element is going to be ./caesar,
and then the next element is going to contain the key that the user typed in.
Now, if they used it correctly for the usage of Caesar,
then they're going to type in a number.
But even though the character that they type is a number,
it's of data type string.
>> So how do we convert that string to an integer?
So say I have num, a string, containing the string 50.
If I want to convert that to an integer, then I simply
declare a new variable, an integer i, calling atoi.
I pass in my string variable, num, and then i will then contain the number 50.
Make sure to check the man pages for the atoi function
to check which library it's in, as well as what value it
will return if the string passed in doesn't contain all numbers.
>> So now that we've gotten the key, the next step
is to get the plaintext from the user.
Now, this is going to be less complicated
than navigating around the command line arguments.
All we have to do is call the getstring function
to prompt the user to give us a string, but remember
to check the specifications for how we might want to prompt the user for that.
>> Now we come to the heart of the problem--
how to encipher the plaintext.
Well, first, let's talk about how to encipher one character at a time,
and then we'll address how to iterate over the entire plaintext.
I've written some pseudocode for the Caesar problem.
I encourage you to write your own as well.
It might not look identical to mine, and that's OK, but as long
as the general idea is the same.
>> The first three steps we've already done.
We've gotten the key from the command line argument,
we've turned that key into an integer, and we've
prompted the user for the plaintext that they want to encipher.
So then the next big chunk is that for each character
in the plaintext string, if it's alphabetic,
we want to preserve its case and shift it.
By preserve case, what I mean is that all upper case
letters should remain upper case and all lowercase letters
should remain lowercase.
So then after we shift those, then we print the ciphertext.
>> Here are three functions that are going to come in handy for this problem.
Remember up above when I gave the example for shifting this is CS50?
Remember that the 50 and the exclamation mark didn't shift?
So how can we tell whether we need to shift a letter or not?
Well, "is alpha," if you pass it a character,
will return true if that character is a letter and false otherwise.
To help you with preserving capitalization
are the functions "is upper" and "is lower."
>> These two functions also take in a single character as input
and return you a Boolean, either true or false
depending on whether that character is upper case or lower case.
Because "is upper" and "is lower" are Boolean functions,
meaning that they return you a Boolean, you can use these in your conditions.
So here's a snippet of code that only prints a letter if it's upper case.
So I've declared my character letter to be the upper case zed
and then if "is upper" returns true, then I print that letter.
>> Going back to our simple example of shifting the alphabet by a key of two,
how do we actually get that to work?
Well, it turns out that characters and integers are very closely related.
Each character has an integer value associated
with it found in the ASCII chart, where each character's ASCII
value is displayed.
So an upper case A corresponds to an ASCII value of 65
and a lowercase a to an ASCII value of 97.
>> Feel free to look up any ASCII chart online
to see these values for yourself.
So what this means is that we can take the character of upper case A,
add the integer two to it, and then get the character upper case C as a result.
That's because 65, the ASCII value for capital A, plus 2,
gives us 67, which corresponds to the character of upper case C.
>> Unfortunately, things won't quite be so simple.
We have an equation that we have to consider.
Here it tells us that the ith ciphertext letter corresponds to the ith plaintext
letter, plus the key-- all of that, modular 26.
Why is that the case?
Let's go back to our example from before, where capital A, plus 2,
gives us capital C.
>> So applying the equation that the specification gives us,
then let's take capital A plus 2 and mod that by 26.
So capital A, when I put it in those single quotation marks,
allows me to treat it as an integer, so that allows
me to cast it to its ASCII value, 65.
65 plus 2 is 67.
67 mod 26 gives us 15, but that doesn't really
make sense because we know that the capital C ASCII value is 67, not 15.
So how do we reconcile that?
>> Well, here I'd like to posit the notion of an alphabetical index.
So we've already talked about how each character has its ASCII value,
but I'd like to say, well, let's think about each character also having
an alphabetical index, where A for instance,
as the first letter of the alphabet, has an alphabetical index of zero.
So now let's apply the same equation as before,
but using an alphabetical index.
>> So A is zero, as we've defined.
So then taking zero plus two, mod 26, that's two, mod 26, which gives us two.
And well, in terms of an alphabetical index,
C is the third letter in the alphabet, so that would correspond
to an alphabetical index of two.
So it seems that using the alphabetical index in this case
actually gives us the correct result.
>> So now let's check to see if the equation works
with an alphabetical index.
Y's alphabetical index is 24 as the second to last letter in the alphabet.
So then 24 plus our key of two gives us 26.
26 mod 26 gives us 0, which, lucky for us, is the alphabetical index for A.
So hopefully that's proof enough that the alphabetical index method works.
If not, feel free to try out some examples of your own.
>> In order to properly wrap around the alphabet and apply the Caesar equation,
then we know that we need to deal with alphabetical indices.
But we start with ASCII values, and only then
do we then convert to the alphabetical index.
From there, in order to print, we need to deal with the ASCII values again.
So we need to figure out how to go from ASCII to alphabetical
and from alphabetical to ASCII.
>> So I leave it to you to figure out the pattern between a character
and its alphabetical index and its ASCII value.
Now, remember that even though this table right on the slide
shows the capital letters, we also have to consider whether or not
a different pattern applies for the lower case characters.
>> So now that we've figured out how to shift a single character,
then all we have to do is scale that up to go across the entire plaintext.
So the plaintext is a string.
Lucky for us, a string is really just an array of characters,
so in order to access every character of a string, all you have to do
is to use array notation.
Say I have a variable of type string called "text='this is CS50.'"
>> Well, then, in order to access each character,
all I have to do with the variable text is
to say well, text at index zero, that corresponds to capital T. Text at index
one corresponds to the lower case h.
Another useful function is the string length function.
So passing in a string to that function will return
an integer, the length of that string.
>> Now that we've talked about all these different elements,
let's put them back together.
So return to either my pseudocode code or your pseudocode
and go through and make sure that you know how to do every single thing.
Getting the key using argc and argv, turning the key into an integer, a
to i, prompting for plaintext, getstring, and then iterating
over every character in the plaintext string,
preserving the case of each character and shifting that character by the key,
ensuring that you're wrapping around the alphabet,
finally printing that ciphertext.
My name is Amila, and this was Caesar.