>> Hello, everybody.
Welcome to walkthrough 2.
As we begin our third pset in cs50, this week focusing
on cryptography; so taking some message
that someone else can read and encoding it
so that you can't read it unless you know the keyword.
So this was today's music; a band called Rehab.
I like them very much.
So as the pset says several times, before you do anything
with this pset, before you try to submit,
please update your appliance.
We've released a new version of our submit50 program
that hopefully addresses some of the issues
that some people ran into.
So to get that new version you just have to say
"sudo yum, dash, y update."
That's going to pull down a bunch of updates.
Please don't close your laptop or anything
like that while this is happening.
If you get a message saying it can't find the meta link
or something like that, that just means
that your Internet's not connected.
Check out "manual, dot, cs 50, dot, net, slash,
faqs" for some instructions on how to get that working again.
Just a reminder, it's going to ask you for your password,
which is just J Harvard's password which is "crimson"
and you're not going to see it as you're typing it just
for security purposes.
And same thing with submit50, when you enter
in your cloud user name and password, you're not going
to see your password as you type it.
So don't worry, the terminal's not frozen,
you're just not seeing what you're typing
for security purposes.
So this -- yup?
>> Oh, sorry.
How long ago was that updated to the website
because I think I did that before I submitted my last pset?
>> Oh, so how long ago was this -- the yum update ready to go?
So we're just going to be -- keep releasing these basically,
so it's always good to just make sure you have the
latest versions.
Yeah, so anytime we -- someone runs into a problem,
we're going to fix it and we're going to release it
and then you can get the new version by simply doing this.
>> All right.
>> Doing this when there's no new version won't hurt
your computer.
It will just take two seconds/, it will say,
"no new updates available."
You're ready to go.
So do this as much as possible.
It won't hurt/ other questions with submission problems?
Okay, cool.
That's good to hear.
So this week it's also good to focus on backing up your code.
So when you run the submit50,
you're technically submitting your code; however,
submitting your code on a Tuesday
and then submitting again on a Wednesday,
there's nothing really wrong with that.
And what happens when you submit it is you're sending it
over to the CS50 server.
So if you drop your laptop or it goes swimming or something
and you lose all your code, there's not to worry
because you've backed it up on the CS50 servers
and we can get you a copy back really simply.
Now, there's also Dropbox integrated to the appliance.
So you might have heard of this.
It's a little program
that basically synchronizes some folder with the Dropbox server;
so it will just run in the background,
and every time you make a change to a file or create a new file
and put it inside of that Dropbox folder,
it's going to synchronize it and back it up so you'll never have
to worry about losing those files.
So I'd encourage you to try out both of these options as a means
of backing up your code.
And finally, we can also get code off the appliance
really easily.
So one way to do this is to just to e-mail a bunch of files
to yourself but that gets kind
of tedious once you have a lot of files.
And so here are two ways documented
on manual.cs50.net/appliance again.
But really basically what you can do by simply entering
in these two simple commands is create a folder on your desktop
that is The Appliance.
So it will look like any other folder on your computer
but you'll actually be accessing the files inside
of your appliance, so you can copy things back and forth.
So questions on some little appliance tricks?
Happy to show you more if you're curious.
So the first problem on this problem set is called "Old Man."
So what we need to do here is produce output
like this except ten more verses of this,
basically outputting the song "This Old Man."
And so our to do list here isn't too bad.
So we basically need to do two things: We need to loop
over our verses, right, because we have ten verses
of which they're all pretty similar,
so feels like the loop would be a good idea to leverage here;
and then as we're looping over them we want
to display the entire verse.
So there are several different approaches we can take here.
So as I said, each of the verses is only slightly different
so there's a few things we could do.
We could say "store the verses in variables," right.
There's a lot of repeated text so if we save that text
in a variable and output that text
and then only output the different text,
then that's one way to approach it.
Or we can do something like "use conditions," where we can say,
okay, well, if I'm on the first verse, I'm going to say this.
Rather than, if I'm on the first verse,
I'm going to use this variable.
We could also use arrays here.
So we haven't really gotten into arrays too much yet,
but we certainly will in the coming week,
but this is another opportunity to use arrays.
We can put all of our verses in an array,
and then go through that in order
to output the correct song lyrics.
Okay, so that's done.
So now how can we display each verse?
So this is a great opportunity to start using functions.
So up to this point we've basically seen functions
that other people wrote for us.
Like printf is a function, get int is a function,
but we didn't actually write those functions.
Of course, we can write our own functions,
and that's where programming gets really fun.
So a function is basically a block of code aimed
at accomplishing a single task.
So something like get int.
It has the single task of getting something from the user
and giving it back to you in a variable.
So functions can take input in the form of arguments,
so we can say, I want to display the first verse;
I want to display the second verse; and they produce output.
So they can return some value, they can print
out to the screen, they can do whatever you want.
So in this case we have our single task.
We want to display a verse.
So as our input to this function we might want to say which verse
to display, you know, one, two, three, four;
and our output is going to be the text of the verse.
Whether you return that or print that directly
to the screen, is up to you.
So that's it for Old Man.
It's a good warm up exercise.
But any questions on how you might want to approach that?
Okay. So let's get to the more interesting two problems.
So the first of the two ciphers you'll be implementing is called
the Caesar cipher.
So this is what a good output
of your program is going to look like.
You're going to run Caesar and you're going to supply it now
with what's called a command line argument.
So rather than asking the user to type in 13,
we're going to specify some number
when they actually run the program.
Then after that, you're going to prompt the user for some input
or the message that they want to encrypt,
and then you're just going to spit out the encrypted message.
So here's our outline of what we want to do.
We first want to determine what that number is
that the user typed in at the command line.
In this case it was 13.
And so throughout our program and in the pset specification,
this is just our k; k for key.
So after we determine what that is,
we want to ask the user what the message they want to encrypt is.
Then we want to loop over each character of the string
and encrypt it and output it to the user
so we have an encrypted message.
So let's take a look at how we're going to get
that number off the command line.
So you'll notice before that we had inside
of our main declaration -- oh, question first.
>> Sorry. Would you mind going back to the previous slide.
>> Yup.
>> [Inaudible]
>> Sure. So once we have the message,
we want to encrypt that message.
So that means we want to encrypt every letter.
So in order to do that, we want to have some form of loop
that goes over every letter in the string, does something
to it, and then spits back what the encrypted character
should be.
So by doing that, if we do that for every character
in the string, then eventually we're going
to have our totally encrypted string
and we can send it back to the user.
Okay, so before when we use main we just said "int main void."
And that basically said that, okay,
I have this function called main
but it doesn't take any arguments
so I can just say void; however,
the main function can take arguments,
and those arguments come kind of magically from the command line.
So there are two arguments to our main function.
The first is called argc which stands for arg count
or the number of arguments that have been given,
so this will always be a number.
The second of these is argv, so this is an array of strings.
So everything that I've typed at the command line,
including the program itself, is going to be placed
in a block inside of this array.
So if I run caesar 13 at the command, line when I'm inside
of main, I have an argc of 2, because the name
of the program counts;
then I have my first arg value is the string caesar,
and the second is the string 13.
So we don't want to use a string as our key, right?
We don't want to try to move things over by strings,
we want to add numbers.
So the first thing we need to do is convert this string
which is inside of argv to a number that we can use.
So there's a special function that's defined for us called "a
to i," [pronounced] and this takes one string as an argument
and it returns the integer that's enclosed inside
of that string.
Now, if I had something that's not a number inside
of the string, it's just going to return zero, so we don't have
to worry about error checking as the pset says.
Yup?
>> So is atoi automatically included in, like, this CS50
or one of those standard io -
>> Yup. So is atoi automatically included?
Nope. You're going to need to include a separate header file
which we'll see shortly.
So yes. So it's a new one that we're going to need.
Other questions?
Yup?
>> [Inaudible] about a number is [inaudible] return zero?
>> Sure. So in this case we have a number, right, our string a,
it just contains an actual integer.
So in this case it's going to return 50.
Now, if I said something like, string a equals word,
and then I said, atoi on the string,
it's going to return zero because word isn't a number
so atoi's going to say, well, I'm just going
to give you back zero because that's clearly not what
you wanted.
Yup?
>> Does that work for nonletters as well?
Like a comma or something like that?
>> So does this work for nonletters as well?
Yeah. If there's anything inside
of this string that's not a number,
atoi's going to say zero.
So it has to be purely an integer for you
to get back a valid value.
Yup?
>> For argv, how does it distinguish
between two separate strings?
Like, you have the first string and you have the second string,
and I remember you mentioned a lecture
like this something you used to distinguish between the two.
>> Sure. So how does argv kind of break up the arguments
into separate blocks in the array?
So spaces.
So if I said caesar 13, space, word,
then my argv would have three elements in it, maybe caesar 13,
maybe c013 and the string word.
So everything that's separated by a space is going
to be a new element inside of argv.
>> I mean inside actual array though, how does it know that,
like, this -- does it just put arg, program name,
and then what you inputted, like, together in the array?
So then how would it know --
>> So argv is an array and it has argc number of elements.
So the first element in the array is kind of --
each element in the array is kind of separate
from the next element.
So this all happens for you.
You don't want to try to determine
like where it's end and don't end.
So it's going to break everything up by spaces,
and then the first thing is going to go in 0;
then the next word, if there's a space,
is going to go into one; and so on.
Yeah. So this is all done for you and we don't really have
to worry about how it happens, we just need to know
that argv has an array of all the strings that were sent along
when we ran the program.
Okay, so let's take a look at an example
of using this argv and argc.
So if we go into the appliance and open up this args.c,
so now instead of saying int main void,
we're now saying int main, int argc, and now string argv
because this is an array of strings.
So these two brackets tell me
that this is not just a single string
but this is actually an array of strings.
So now I can do something like iterate over everything
that was given to me at the command line.
So we're going to use a four loop,
so i is our counter variable, and we know how many things are
in this array because they are argc number
of things in the array.
So I can say, while i is less than argc, I can print out argv,
the brackets, and i; so that's going to say go
to the ith location -- so zero, one, two, etc. --
get the value there, and I'm going to print it out.
So now you'll notice that we're no longer using percent d
for strings, but this new one, percent s. So s for string,
which makes a lot more sense than d for integer.
So if we run this program, you could say, make args --
so if I said just args, it's going to print out one thing.
It's going to say the zeroth thing
in the array is just the program itself including that dot slash.
So now if I say args one, two, three,
now see that that our argv array has four things in it.
So in the first spot is our program name,
and then after that in every next spot we have these words
that I typed in that are separated by spaces.
So remember that the counting starts at zero not one,
so the first thing is going
to be the first argument that's not the name of the program.
So questions on how I'm using these command line arguments
or argc or argv or whatever that is?
All right moving right along.
>> Can you say the code again, please?
>> Oh, sure.
So we can walk through the code again.
So here we go.
So no longer is it int main void.
I now have two things.
The first argument is always argc;
the second argument is always an array of strings,
so string argv, and then these brackets that say it's an array;
and now I'm going to iterate over this array.
I know how many things are in it so I can say, well,
i is less than argc and I know the first thing is zero,
so I can start my counter at zero;
and now I'm just going to printf two things.
So the percent d is going to get substituted with i,
which is the position in the array that I'm at,
and the second thing is going to be the value in that array,
so what the actual string is that I type said.
Yup?
>> What's the percent s?
>> So the percent s is just like percent d except for strings.
So percent d for integers, percent f for athletes,
and percent s for strings.
So everyone kind of see what we're doing here
and how this works?
Yup?
>> Argv is like the name of the array?
>> Yes. So argv is the variable name; so it's argument values.
And so this is just a convention.
>> Could we [inaudible].
>> Yeah, so by convention we should use argc and argv.
Yeah.
>> In our program it's going to be like another name
if the array's used to represent, for example, numbers?
>> So you could, but just -- it's very common in c programs
for there to be argc and argv, so it's just kinds
of a convention that when people see argv, they're like, oh,
okay, so that refers to the command not arguments.
So it is best to keep these named as they are.
[ Pause ]
All right.
So --
[ Pause ]
all right.
So that's done.
So now we have k, we've converted this string
to an integer, and we're ready to use it
to encrypt our message.
So the next thing we need to do is prompt the user
for the string to encode.
So remember in pset1 we were just dealing with numbers,
like numbers of pennies and number
of males spotting females.
So we could just use get int or get long long.
Now we're going to be using strings
and so we have another function written
in the CS50 library called "GetString."
So this is just going through the same thing
as get int except it's going to allow the user to type in words.
And it will return to you, just like get int,
a string rather than an integer.
So I can say something like string name equals GetString,
so I'm ready to receive input from the user.
Once they hit enter, the value is stored in the variable name
and I can say "your name is" and output the string,
again with that percent s, s for string.
Okay, so that's done.
We now have the string from the user,
and so now we actually need to encrypt it.
So we need to loop over every character of the string,
and then we're going to encrypt and output each letter.
So how can we loop over a string?
Well, a string is actually just an array of characters, right?
That makes sense because a string is basically letters,
and if each letter is a different element,
we essentially have an array.
So there's a special function called strlen that's going
to return the length of a string,
so how many characters are in the string; things like periods
and spaces or numbers all count.
So if I wanted to get a string from the user
and just spit it back to them, I could use something like this.
So I'm going to say, string word equals GetString.
So, again, I'm going to prompt the user for a string
and store it inside of word.
So now I want to loop over that string.
So in order to loop over it,
I need to know how many characters it contains.
So to get that, I can just use strlen.
So I call strlen on a string and it's going to give back
to me an integer that tells me how many characters are in it.
Okay, so now I know where it starts and where it ends,
and I can have a loop that goes over it.
So start our counter off at the beginning of the string,
we're going to go until we hit the end of the string,
and for each letter inside of the string,
I'm going to output it.
So because a string is an array, which, again, we'll see more
in lecture in section, we can access the ith element
of the array, so zero, one, two, with the same bracket notation.
So if I say, word, bracket, zero, that's going
to give me the first character.
If I say word, bracket, one,
it's going to give me the second character, and so on.
So questions on how we're going through each character?
Yup?
>> Why does it say inth length if it's not an integer?
>> So why does it say inth length?
Because it actually is an integer now.
So strlen stands for "string length," which is the number
of characters in my string.
So that's always going to be an integer
because we can't have negative, we don't have decimals,
so it just makes sense for this to be an integer.
Yup?
>> What's actually encrypted [inaudible]?
>> Right. So this is not encrypted.
So this is actually just spitting the string right back
out at the user, because we're not actually doing anything
to word i. We're just outputting it back.
Yup?
>> For the string, when it's the array of characters,
does it only contain the characters in that string
or does it include anything else at the end?
>> So, yeah, so it is at the end of it going
to have this special character representing Null,
which we'll see in lecture shortly, but, yes,
so there's a special character at the end of every string
so that you know when it ends,
and that's basically how strlen determines how long the
string is.
It basically goes through the entire string, says, okay,
once I find this character, that means the string is done
and I know how many characters it has.
Yup?
>> Does this go through all the strings for you or do you need
to do this separately for each [inaudible]?
>> So this is going to go through a single string, right.
We have one string here and it's called "word."
So we're going to go through that one string one time
and output every character one time.
So if we had multiple strings and we could go through each
of them separately or store them in a multidimensional array,
which I'll see in section, and that's going
to look pretty much the same.
Other questions on how we're going
through every letter of a string?
Yup?
>> Can you tell what letters are in the string or [inaudible].
>> So can it tell you what letters are inside
of the string?
Sure. So as we're going through this string,
this word i is the current letter in the string,
so I'm starting off at zero.
Now, once it's at zero, this word i is going
to be the first character in the string,
so the actual first letter.
So if I wanted to do something like determine
if the sting contains a letter, than I can go
through the entire string and say, okay, if this -- is this --
is my current letter equal to letter I'm looking for?
If it's yes, then I can return I found it, if it's no,
then I can keep looking.
Does that make sense?
Yup.
>> Can a string include multiple words and, like, spaces?
>> Yes. So can a string include multiple words and spaces?
Yes. So you can have spaces inside of your string,
that's fine; you can have numbers and characters.
What you can't do is --
the difference being the command line argv thing,
strings are separated by spaces,
so you need to enclose it in quotes.
But just with any regular string, like this one here,
we can type spaces and it will be inside the string;
where before argv kind
of separates the different strings by spaces.
Other questions?
Yup.
>> So [inaudible]
>> Sure. So right now word is a string,
and a string is just an array of characters;
an array being a list.
So now I can access different elements of that array,
so different kinds of buckets that inside of the array,
with this bracket notation.
The name of the array, a bracket,
and then the position I want to access.
So for -- as i goes over the string,
I'm going to access each bucket in my array which corresponds
to each letter in my string.
Yup?
>> So a string length also gives the length
of a string including the spaces, right?
>> Yes. So when I call strlen, that's going
to include literally everything in the string --
spaces, characters, numbers, all that stuff.
All right.
So now we know how to loop over every character of the string,
and now comes the actual fun part, the encryption.
Though what do we do with each character so that when I send it
to someone else, they have no idea what I'm trying to say.
So we're going to implement two different ciphers:
The first is called the Caesar Cipher,
and this is the formal mathy definition, but I'm not good
at math so let's break it down.
So c sub i is going to be the ith character
in the cipher text.
So we have a few components here.
The first is the plain text.
This is what the user typed in, the readable message.
Now, c is going to be the cipher text or the encrypted text,
the after I ran my algorithm, what each letter is encrypted.
And finally we have some key which says, how am I going
to encrypt each letter.
So we have the ith letter in the cipher text is equal
to the ith letter in the plain text; so the first letter
in the encrypted message and the first letter
and the message the user typed in is equal to that plus --
so the letter these are typed in -- plus some number.
So if I said, 2, then k would be 2 in this case,
and I can just say I want two letters
after whatever p of i is.
Now, this end is the module operator which we may have used
in last pset, and this just basically says things
should wrap.
So after z, I shouldn't start outputting numbers and symbols,
I should wrap back to a. So questions
on the Caesar Cipher or how it works?
Okay. So let's take a look at an example.
So my string is, of course, "This is CS50."
In this case my k is 13.
So I'm going to start at the beginning of my string
and I'm going through every letter and add 13 to it.
So I start at T and 13 letters later, happens to be G.
So you notice that I didn't --
because 13 would have taken me past the end of the alphabet,
I wrapped around to the beginning.
So I go through and do this
for every single letter inside of my string.
So you notice I'm not changing the spaces,
so the spaces don't become any other symbols ;
'm not changing the numbers, which stay 50;
and I'm not changing the symbols like this period.
I'm only changing the letters and I'm making sure
that the capitalization is preserved.
So T becomes a -- capital T becomes a capital G,
capital C becomes a capital P, etc. So questions on how we went
from "This is CS50" to whatever that says?
Yup?
>> Is it adding 13 to the ASCII number or is it adding 13
to the alphabet number?
>> So is it adding 13 to the ASCII value?
So we're going to ASCII right now.
The answer being yes.
Yup?
>> So we need to encrypt the numbers five-zero or no?
>> So do we need to encrypt the numbers?
No. We're only encrypting letters.
>> And spaces I guess would be also [inaudible].
>> Yes. So numbers we do nothing and symbols we do nothing.
Like the period stayed a period.
And space really is just a symbol,
there's nothing really special about a space,
so we can just leave it alone.
All right.
So yes. So to answer that question,
how are we actually adding things to letters?
So there's something in C that's called ASCII,
and ASCII is basically a mapping from characters to numbers.
So in ASCII we have the character upper case A,
and the mapping, it's going to say, this A,
that's equal to the number 65.
And a lower case a is equal to the number 97.
So if you go to this ASCII table dot com, you can see a long list
of all 127 of them that maps every number from 0 to 127
to a different character on your keyboard,
or maybe not on your keyboard.
So let's take a look at what that actually means.
So we open up our appliance, and we're going to go over here
to ascii.c. so here we have two things: First, we're declaring a
"char" or a character.
So you notice that I'm single quotes here.
Where strings I use double quotes
and strings contain multiple characters and numbers;
where a char is just a single character.
We can't have more than one thing in here
and it's going to use single quotes.
So it also declared a corresponding number;
so int number equals 65.
You'll remember that the ASCII value of a or the number
of that represents the upper case A is 65,
so I can actually print both of these as chars.
So this percent c like percent D for int, percent C says,
print out the character represented by the letter.
So I can print out upper case A, or I can convert that 65
into the ASCII letter
and so this will also print A. Similarly,
I can print both as integers.
So I can say, okay, I want the integer
that this ASCII letter maps to, which is 65,
and then the second one is already an integer
so I can just print 65.
So does that make sense what these two blocks are doing here?
So basically back and forth
from the ASCII number to the ASCII letter.
Yup?
>> Is it like implicit typecasting?
>> Yes. So it is implicit typecasting.
If C says, okay, I want to convert this number to an --
this character to an integer, I can just do that because they're
so -- they're so closely related with ASCII.
So now what we can do is we can do math
with both letters and numbers.
So here we're adding one to the char A,
so can anyone guess what this is going to be?
>> B.
>> Exactly.
I kind of gave it away unintentionally.
So this is going to be an upper case B.
And we can also do something like, I want to print
out the character that's equal to the number --
the ASCII number representing lower case z minus the ASCII
number representing this asterisk, and I want to print
out the character that's represented by that number.
So if I make and run this, I can say, make ASCII and run ASCII.
So here we go.
So remember, this first print is both the integer
and the character and they're both A. Again,
I'm taking the integer and the character and I want the number
that it represents in ASCII, which is both 65.
And so here I'm printing the letter A plus 1;
notice I didn't have to say 65 plus 1.
I can literally say the letter A plus 1,
and C knows that you mean, oh, the number represented in ASCII
for the upper case A plus 1 and convert that back to a letter.
And finally, I have the subtraction of two characters
and that's still going to be a character, just happens
to be upper case P. So questions on ASCII
or how that's going back and forth?
Yup?
>> Can you just go back to the code for one second?
>> Sure. So back to the code, we have a character
which has an ASCII value of 65, and a number 65
that has an ASCII letter of upper case A,
and I can print them out either as letters or as numbers
because they're essentially the same thing using ASCII.
Yup?
>> So using the single quotes designates ASCII as opposed
to a variable called z that's somewhere else in your code?
>> Exactly.
So using these single quotes says this is the value
of my character; where using double quotes would say,
this is the value of my string; and no quotes
at all says this is some variable or function.
Yup?
>> Can you repeat again what the asterisk --
>> Oh, sure.
So right here?
>> Yeah.
>> So both of these are just characters.
So they're defined by ASCII to be some numbers.
So Z is a character and the star even though it's a symbol also
has an associated number.
So I can just subtract those two numbers to get another number
and then in turn another letter.
Yup?
>> If you flip the position of the Z
and this asterisk would you get like an error?
>> So if you flip the position of the Z and the asterisk.
So if I tried to print out negative one- you're saying,
like, try to print out the character represented
by a negative number?
Yeah, you apply it against some weird output thing.
[ Pause ]
okay, so that's ASCII.
[ Pause ]
So now we can utilize ASCII to encrypt our message.
So first we want to forget -- not forget to use this modulus.
So we want to make sure that we wraparound,
so once I start adding 5 to the letter Z, I don't end off
in some weird symbol land because there happened
to be numbers and symbols defined in ASCII
after the letters; however,
we can't just follow the formula exactly.
So we can't just say, okay, well, my p sub i is Z
and my k is 2, then I'm going to mod 26.
So what that's effectively going
to do is create an upper bound of 26, right.
If we're moding everything by 26,
that means it can never be larger than 26.
So this is going to end up being 20 which happens
to some nonprintable character.
But we really wanted this to be B, right?
We wanted to go two spaces over so the first space is an A
and then it's going to be a B.
So that would be corresponding --
the ASCII value of that would be 67, where we just got 20.
So we can't kind of exactly plug into the formula,
but we need to somehow figure out a way to be able to add 2
to something and then convert it back to the ASCII value
of the letter we want to represent.
So that's kind of your challenge
for Caesar is how do we want to do that.
So questions on why just kind
of straight using the formula doesn't work?
[ Pause ]
Yup.
>> Can you say something about the [inaudible]?
>> Yes. So why are we using the mod to begin with?
Just because there are 26 letters and we never want
to go beyond that 26 letters.
So we don't -- so there's effectively some --
like a lower bound and an upper bound of the letter --
of the, like, letters we can use.
So if we mod it, we basically say, okay, I'm never going
to go past that upper bound.
We also need to go make sure we don't go past that lower bound.
So we stay inside this range of characters that we can be using.
So the mod just says, I'm never going to end
up being some value that's too high to be a letter.
Other questions on the Caesar Cipher?
Yup.
>> So for, like, this -- so Z is like 90, right,
so -- so your 92 moding 26?
>> Yeah. Yes.
>> Okay.
>> So if Z is 90, then we basically said,
we're going to say 90 plus 2, which is 92
or whatever the actual value is, and then mod 26 happens
to be 20, which is not what we wanted.
>> So actually [inaudible] --
the examples shows us why mod is a bad thing
but there's another reason it's a good thing.
I don't understand how it's a good thing [inaudible].
>> Sure. So it's a good thing if we do something else first.
So we do want to mod somewhere but we also need to do something
to make sure that we don't end
up in a number that's always less than 26.
>> Isn't 92 a mod 26 like 14 though [inaudible]?
>> Oh, sure.
So, I mean, if Z is -- the math maybe is wrong on this slide
or something, but basically the point is that we're never going
to get something that's what we want.
We're always going to end up below 26 if we mod by 26.
So we need to do something to get us back up into the letters.
>> Oh, I got.
>> Okay. Yup?
>> Is 26 mod 26 zero or --
>> So 26 mod 26 is zero because 26 divided
by 26 has a remainder of zero.
Other questions?
Okay. So just to keep in mind when you're going through this,
remember that capitalization is important, so we don't want
to convert upper case letters to lower case letters
and vice versa; we want to make sure
that letters never become symbols;
and we want to make sure that symbols are never changed.
So questions on Caesar before we move on to Vigenere?
Yup?
>> So when we encode our phrase, do all of the capitals
and lower case [inaudible] at the same time?
>> Yes. So when we encode our phrase, all of the capitals need
to stay intact and all the lower case need to stay intact.
Other questions on Caesar?
Okay. So let's move on to Vigenere.
So unlike Caesar, instead of specifying a number for a key,
we're going to specify a word.
So in this case we're basically going
to get a different encryption of the same phrase
which is "This is CS50."
If I used a different word here, then I'm going
to get a totally different encryption.
So, again, here's our outline.
It's very similar to Caesar because we want
to read this word from the command line that we're going
to be using to encrypt the string.
We're going to prompt the user for what we want to encode.
Then we want to do two things now: We want to loop
over the string, and as we're looping over the string,
we also want to loop over this keyword,
because in each case we want to use the next letter
of the keyword to encode the next letter of the plain text.
And then we want to output each encoded letter.
So first, let's just take a look at getting the input.
It's very, very similar except it's actually a little easier
this time.
Because argv contains strings,
we want our keyword to be a string.
So we're all set.
We don't need to call atoi again to convert
that string to an integer.
And just to get the plain text,
we're going to do the same exact thing.
We're just going to call it GetString, and then we're going
to get the string that we want to encrypt.
So those two steps are very similar to Caesar
and actually a little bit easier because we don't have to worry
about that atoi function.
So now we want to loop over the string and we want
to apply this different cipher.
So the only difference in this formula
than from the Caesar formula is now we have this k subj.
So before, this k was the same thing
for every letter inside of the plain text.
Now this k is going to vary.
So now it's the jth character, so not i because my plain text
and my key can have different lengths,
so they're not always -- i and j are not always the same thing --
so the jth character in my keyword.
So I'm going to iterate over my keyword; once I reach the end
of the keyword, I'm going to start over
and start iterating again.
And, again, we want to make sure we mod by 26 so that things wrap
and I don't end up printing symbols.
So here's an example.
So now we have "This!
is CS50," which sometimes happens
when David's mic is too loud, and we're adding
in the keyword "tommy."
So you'll notice that in each letter of my --
each letter of my plain text is using the next letter of tommy.
So I'm not just adding 13 every time.
The first time I'm adding a t to an m
which produces an M. You'll notice, again, capitalization
and things like that are preserved.
Symbols are untouched, spaces are untouched,
numbers are untouched.
So you'll notice as we're going through each letter
of the plain text, we're going through each next letter
of the keyword, and once I've reached the end of my keyword,
which is at the i, I'm going to start over.
So I'm going to go back to t, and then continue on with o-m.
So questions on this Vigenere's working?
Yup.
>> [Inaudible] the [inaudible] number like from ASCII
of that character, like of -- like m is 13 and we're adding
that to the i, is that what we're doing.
>> Yes. Essentially, yes.
So that this t has some ASCII value,
my lower case t has some value, and we're going
to add them together and we're going
to produce some other value.
Yup?
>> So what if your keyword was longer than your string,
would you [inaudible]?
>> So if your keyword is longer than your string,
then you basically don't ever need to restart the keyword.
You could just use it up until your plain text it done
and we don't ever need to go back
to the beginning of the keyword.
>> Oh, yeah, okay.
>> Okay. So now you'll notice
that we're changing each character by a different amount.
So after each letter, we want to go to the next letter
in the plain text and the next letter in the keyword
which could result in going back to the beginning of the keyword
but not back to the beginning of the plain text because we want
to make sure we get through the whole thing.
But we don't want to go to the next letter of our keyword
if we encounter a symbol.
So you'll notice here that we have the exclamation mark after
"this," so that didn't kind of burnout our y. We saved the y
until the next thing that was a letter.
So if you encounter something that is not going
to be encrypted, including numbers and symbols,
you don't want to move to the next space in your keyword.
So that means that somehow we need to keep track
of both our position in the plain text and our position
in the keyword, so we know what two values to add together
and when we need to start going back
to the beginning of the keyword.
So having the length of both using maybe strlen is probably
going to be helpful as you're going through your program.
So that's kind of our outline for Vigenere.
It's very similar to Caesar,
the only difference being we're not just going
to simply add a number each time, but we're going
to add a different number each time making sure to restart
at the beginning of our keyword as necessary.
So does that make sense
to everyone how we can go about doing that?
[ Pause ]
Okay. So before we wrap up,
let's talk about a little bit about design.
Don't forget, in this pset and every pset,
style is very important and very easy points to get,
so just make sure that your indentation is clear,
you're commenting your code, your variable names make sense.
Now you're going to start creating functions
so having function names that make sense and not things
like single letters or anything like that.
So now, design, another access you'll be graded on.
So one of the major things
that shows good code design is this DRY principle which says
"Don't Repeat Yourself."
So if you notice that when you're writing code you're kind
of like, oh, I got to copy/paste something and use it over here,
you know, copy/paste it, use it over here.
That's usually not a good thing because you're kind
of rewriting code that you don't need to rewrite.
Similarly, if you're kind of rewriting the same logic
but just tweaking it a little bit all over the place,
that's probably also not good design.
So the solution to both of these problems, this copy/pasting
and kind of just tweaking logic depending on where you're
on the program, is to use functions.
So because a function is a block
of code you can call whenever you want,
it's effectively reusable, right?
I can use the function to display a verse here;
I can use a function to display a verse
in Old Man somewhere else; and that will allow me to not have
to write out the "display this verse
in old man" a bunch of times.
So it also allows you to organize your code a lot better
because you can break up these large problems
into smaller problems.
So you might want to say, okay, I have this large problem .
I have this word and I need to output some cipher text.
So a smaller problem might be, okay, I have this letter
and I need to output the encrypted form of this letter.
So putting that together, I can keep using this letter function
and eventually have an entire word.
So it's always good to take some big problem and break it up into
as small a problems as possible and then kind
of combine these smaller problems to get the solution
to the bigger problem.
So having functions that do a single task even
if it's something small is a good idea.
So last week a lot of people were asking, well,
where is this list of functions or something.
So we have on cs50.net a very large list
of all the helpful functions in C. So this just happens
to be cs50.net/resources/cpp reference.com/stdstring;
and so these are all the relevant string functions you
might want to use.
So this is just a very comprehensive list.
I can navigate here to just C Reference,
and I can see here's my string functions, my math functions.
I can click this, see a bunch of helpful math functions.
Want to click on one, it tells you exactly what header file you
need to include, and it tells you what the function does.
So in this case this is the absolute value function.
So in order to use it, I need to make sure
that I include stdlib.h, and then I have this function
"abs" available to me.
So it takes one argument, it's an integer, it's a number,
and you can see it returns the absolute value of that number.
So that link might be really helpful if you're looking
for this comprehensive list of C functions
because we haven't really been using C that much
so you might be not aware that some function exists,
so you might want to poke around that page to find
out if what you're trying to do has already been written.
So just make sure before you leave to make sure
that you update your appliance
so you have the latest version of everything.
So any last questions on Caesar, Vigenere,
the pset sections, logistics, anything?
Yup?
>> Well, what's up with returning 0 and returning 1?
>> Sure. So inside of the pset it says, you need to return 1
if there's some kind of error occurred, right?
So this is another convention in C. When a program goes
through successfully, usually at the end of main you might say,
return 0, which means, return
if there are zero errors in my program.
So if you -- if our program returns something that's other
than 0, that usually signifies that something went wrong.
So, like, well, some of you were using Virtual Box,
you sometimes saw like error code 355 something.
So this is kind of like Virtual Box just returned some number
that wasn't 0.
So in this case we ask you to return 1.
So the special value 1 just says to the programmers,
anyone running your code, or automated tests or anything
like that, that something went wrong.
And so that's why we want you to return 0
if everything went well; and if something goes wrong,
then you want to return 1.
Other questions on the pset?
All right.
If not, then good luck with Crypto.
Don't forget about help.cs50.net.
You'll get really fast answers.
And good luck.
[ Silence ]