1 """A set of ciphers with implementations for both enciphering and deciphering
2 them. See cipherbreak for automatic breaking of these ciphers
7 from language_models
import unaccent
, sanitise
10 def caesar_encipher_letter(accented_letter
, shift
):
11 """Encipher a letter, given a shift amount
13 >>> caesar_encipher_letter('a', 1)
15 >>> caesar_encipher_letter('a', 2)
17 >>> caesar_encipher_letter('b', 2)
19 >>> caesar_encipher_letter('x', 2)
21 >>> caesar_encipher_letter('y', 2)
23 >>> caesar_encipher_letter('z', 2)
25 >>> caesar_encipher_letter('z', -1)
27 >>> caesar_encipher_letter('a', -1)
29 >>> caesar_encipher_letter('A', 1)
31 >>> caesar_encipher_letter('é', 1)
34 letter
= unaccent(accented_letter
)
35 if letter
in string
.ascii_letters
:
36 if letter
in string
.ascii_uppercase
:
37 alphabet_start
= ord('A')
39 alphabet_start
= ord('a')
40 return chr(((ord(letter
) - alphabet_start
+ shift
) % 26) +
45 def caesar_decipher_letter(letter
, shift
):
46 """Decipher a letter, given a shift amount
48 >>> caesar_decipher_letter('b', 1)
50 >>> caesar_decipher_letter('b', 2)
53 return caesar_encipher_letter(letter
, -shift
)
55 def caesar_encipher(message
, shift
):
56 """Encipher a message with the Caesar cipher of given shift
58 >>> caesar_encipher('abc', 1)
60 >>> caesar_encipher('abc', 2)
62 >>> caesar_encipher('abcxyz', 2)
64 >>> caesar_encipher('ab cx yz', 2)
66 >>> caesar_encipher('Héllo World!', 2)
69 enciphered
= [caesar_encipher_letter(l
, shift
) for l
in message
]
70 return ''.join(enciphered
)
72 def caesar_decipher(message
, shift
):
73 """Decipher a message with the Caesar cipher of given shift
75 >>> caesar_decipher('bcd', 1)
77 >>> caesar_decipher('cde', 2)
79 >>> caesar_decipher('cd ez ab', 2)
81 >>> caesar_decipher('Jgnnq Yqtnf!', 2)
84 return caesar_encipher(message
, -shift
)
87 if __name__
== "__main__":