lab 2 - shift and affine ciphers (jan 31)

task 1: write a function shift(s,k) that takes in a string s and an integer k (the key) and shifts each alphabetic character in s by "adding k mod 26." do not modify any punctuation/spaces. return this ciphertext in upper case. test encryption and decryption (by shifting by -k) for the plain text message "Caesar is #1! (chronologically, for the ciphers we consider)" with the keys k=3 and k=15.

here are some python commands that may be helpful, though not all are necessary. recall (a+b)%m returns the remainder of (a+b) upon division by m. you can access each element of a of a string s the same way you would access elements of a list---either for x in s or individually by, e.g., s[5]. given a character (string of length 1) x, you can obtain the numerical ASCII representation (e.g., 65 for A, 66 for B, etc) with the command ord(x). conversely, you can go from the ASCII representation y back to the character with ord(y). you can also test if a character x (or a whole string) is alphabetic by x.isalpha(). lastly, you can cover an entire string s to uppercase by s.upper().

task 2: write a function all_shifts(s) that takes in a ciphertext s and prints out all possible shifts mod 26 in lowercase, along with the amount of the shift (i.e., the key). (you can convert a string s to lowercase by s.lower().) use this to decode the message XPPEL EXTOY TRSE.

task 3: write a function affine(s,a,b) that takes in a string s and applies the affine shift x -> ax+b mod 26 to each alphabetic character x in s. return the shifted text in upper case.

task 4: write a function invert(a,n) that takes in an integer a and a positive integer n, and returns False if a is not invertible mod n. otherwise, this should return an integer b between 1 and n such that b is an inverse of a mod n. do not use any results on which elements are invertible--just use the definition. then use your function to determine which numbers between 1 and 25 are invertible mod 26.

task 5: write a function affine_dkey(a,b) that takes in an affine shift encryption key (a,b) and returns the coefficients [c,d] of the inverse transformation x -> cx+d mod 26 if the key (a,b) is invertible. if is not invertible, exit with an error message saying this. (the old way to exit with an error is to do something like print out an error message and return -1; a cleaner, more modern way in python is to raise an exception, e.g. raise ValueError("transformation is not invertible"). i recommend the latter, but do not require it.) using this and task 3, try applying affine cipher encryption and decryption on the message "This is affine cipher. But is it a fine cipher?" with the encryption keys (a,b) = (1,3), (a,b) = (7,2) and (a,b) = (13,25).

task 6: write a function all_affine(s) that prints out all possible invertible affine transformations x -> ax+b mod 26 in lower case, along with the coefficients a and b. use this to decode the message RMIKZ MNHMO FMGET QKZYH.

lab 2 homework (due feb 7): complete the above tasks.



labs page
course home