o Moura Alexander Eugent X web.stanford.edu/classics X w eb.stanford.edu/class/cs1 + C Not Secure web.stanford.edu assicstoganandoutsomework crypto We'll say that a "slug" is a len-26 list of the 26 lowercase chars a-z in some order. In a later step, the slug will drive the encryption of each char. The problem at this stage is to compute a len-26 slug from an easily memorized key like 'Bananas!'. All key/slug formation is done with lowercase alphabetic chars. ("slug" is a borrowed typesetting term, referring to a line of letters in a row.) Here is the algorithm to compute a slug from a key: take the lowercase version of the key, and consider only the alphabetic chars in it. The first char is the first char of the slug, the second char is the second in the slug, and so on through all the chars of the key. However, if a char is already in the slug, skip it. A char can never be in the slug twice. With the first few chars of the slug provide by the key, complete the slug by going through the regular alphabet 'abcde...' and appending each char to the end of the slug if it is not already in the slug. The resulting slug will be len-26 and contains every a- z char once at some position. Here is the slug for the key 'Bananas! You can see how the 'b' and 'a' and 'n' go at the front of the slug, followed by the rest of the regular alphabet. compute_slug('Bananas!' ['b', 'a', 'n', 's', 'c', 'p', 'q', 'r', 'd', 'e', 'f','g', 'h', 'i', 'j', 'k', 'l The starter code includes the definition of a constant ALPHABET which is the a-z lowercase letters in a list. You should refer to this constant as ALPHABET in your code at spots where you need the standard a-z chars. Do not change the ALPHABET list; constants like are intended to be a read-only resource for the code, and it's a convention to give them upper-case names like this. Implement the compute slug() function. The 'z' key is so simple, its slug can be worked out by hand, which is how the Doctest was written. compute slug('2')-> ['z', 'a', 'b', 'c', 'p', 'q', 'r', 's', 'd', 'e', 't', 'u', 'f', 'v', 'g', 'w', 'h', 'x', ' 'i', 'y'] ', 'k', 'l', 'm', '1 Stanford C5106A Crypto Project import sys # provided ALPHABET constant - list of the regular alphabet # in lowercase. Refer to this simply as ALPHABET in your code. # This list should not be modified. ALPHABET - ('a', 'b', 'c': 'd', 'e': 'f', 'e', '', '1', '1', 'k', 'l', 'm', 'n', 'o', 'p', 'a', 'T ', 't', 'u', v w , x', 'y', ' def compute_slug(key): Given a key string, compute and return the len-26 slug Ust for it. >compute_slug('2') 1'2', 'a', 'b', 'c','d', 'e', '', '', '', '', '', '*', '2', , 'n', 'o', 'p', 'a', 'r', 's', 't', 'u',v, >> compute_slug 'Bananas!") Ib, ', 'm', 's', 'c': 'd', 'e', '', 'e', '', '', '', '*', 2', '', 'o', 'p', 'a', 'r', 'e', 'y', '', '', >>> compute_slug('Life, Liberty, and) ("l',T,', e', 'b', 'r', 'e', 'y', 'a', 'n', 'd', 'e', 's', '', '', '', '', 'o', 'p', 'a', 's', 'v', 'v, M >>> compute_slug('Zounds!) Iz'o', 'v', 'n', 'd', 's', 's', 'b', 'c', 'e', '', '', '', T, Y', 'R', 'T', '', 'p', 'a', 'r 'e', e zi b. encrypt_char(source, slug, char) The function encrypt_char(source, slug, char) is the heart of this whole program. The function takes a "source" list which is a list of the lowercase characters that can be encrypted, and a "slug" list of the same length which shows the encrypted char to use for each source char. Say we have these lists source = ['a', 'b', 'c','d', ...) slug - i'z', 'a', 'b', 'c ... To encrypt a char: find the lowercase version of the char in the source list. If it is in there, the char at the same index in the slug list is its encrypted form. So in the above example, the encrypted form of 'a' is 'z', the encrypted form of'c' is 'b'. The encrypted output char should have the same upper/lower case as the input char, so the encrypted form of 'A' is 'Z' and the encrypted form of 'C' is 'B'. Do not use the ALPHABET constant in here. Use the "source" parameter - we let the caller of this function specify exactly the source/slug pair they want by passing them in vs. making any assumptions. If a char to encrypt is not in the source list, such as a space'' or comma', then just return the char unchanged. The test case for this uses the 'z' slug, shown here on 2 lines so it's easy to try encryptions by hand. For example 'A' should encrypt to 'Z'. source - abcdefghijklmnopqrstuvwxyz slug - zabcdefghijklmnopqrstuvwxy The provided Doctest looks like this: >>> slug = ['z', 'a', 'b', 'c','d', >>> encrypt_char(ALPHABET, slug, 'A') y') 2 The "slug" line just creates the 'z' slug by hand, and then passes it in to the call to encrypt chart. This way, encrypt char() can be tested independently of mere, the char at the same muex In the slug ISUSTUS UniCrypreu Tom. We above example, the encrypted form of 'a' is 'z', the encrypted form of 'c' is 'b'. The encrypted output char should have the same upper/lower case as the input char, so the encrypted form of 'A' is 'Z' and the encrypted form of 'C' is 'B'. Do not use the ALPHABET constant in here. Use the "source" parameter - we let the caller of this function specify exactly the source/slug pair they want by passing them in vs. making any assumptions. If a char to encrypt is not in the source list, such as a space'' or comma ',, then just return the char unchanged. The test case for this uses the 'z' slug, shown here on 2 lines so it's easy to try encryptions by hand. For example 'A' should encrypt to 'Z'. source = abcdefghijklmnopqrstuvwxyz slug = zabcdefghijklmnopqrstuvwxy The provided Doctest looks like this: y >>> slug = ['z', 'a', 'b' >>> encrypt_char (ALPHABET, slug, 'A' The "slug="line just creates the 'z' slug by hand, and then passes it in to the call to encrypt_char(). This way, encrypt_char() can be tested independently of compute slugo. Alternately, we could call compute slug in the test, in which case encrypt_char() could only be tested when compute_slug was working. In this case, working out the slug by hand was easy enough to do it that way. Doctest quirk: inside the text of a Doctest the "n' must be written with 2 backlashes " '. The reason is that the 'n' expands to an actual newline in the Doctest which messes up the indentation. Using ' ' represents that a newline is desired, but defers def encrypt_char source, slug.chao); Given source and slug lists, if char is in source return its encrypted form. Otherwise return the char unchanged. >>> # Using 'z' slug for testing. >># Can set a var within a Doctest like this. > slug = ['z'. 'a', 'b', 'c','d', 'e', ' t o >>> encrypt_char(ALPHABET, slug, 'A') . th. 40 > encrypt_char(ALPHABET, slug, 'n') > encrypt_char(ALPHABET, slug, 'd') *c >>> encrypt_char(ALPHABET, slug.'.') .. >>> encrypt_char(ALPHABET, slug, ' ') pass