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.