>> 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 ;I'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 ]