Module szyfrow.caesar
+Enciphering and deciphering using the Caesar cipher. +Also attempts to break messages that use a Caesar cipher.
+The Caesar cipher operates one letter at a time. It converts each letter to a +number, then enciphers that number by adding the key. The result is taken mod +26 and converted back into a letter.
++Expand source code +
+"""Enciphering and deciphering using the [Caesar cipher](https://en.wikipedia.org/wiki/Caesar_cipher).
+Also attempts to break messages that use a Caesar cipher.
+
+The Caesar cipher operates one letter at a time. It converts each letter to a
+number, then enciphers that number by adding the key. The result is taken mod
+26 and converted back into a letter.
+
+"""
+
+from szyfrow.support.utilities import *
+from szyfrow.support.language_models import *
+
+def caesar_encipher_letter(accented_letter, shift):
+ """Encipher a letter, given a shift amount.
+
+ Accented version of latin letters (such as é and ö) are converted to their
+ non-accented versions before encryption.
+
+ >>> caesar_encipher_letter('a', 1)
+ 'b'
+ >>> caesar_encipher_letter('a', 2)
+ 'c'
+ >>> caesar_encipher_letter('b', 2)
+ 'd'
+ >>> caesar_encipher_letter('x', 2)
+ 'z'
+ >>> caesar_encipher_letter('y', 2)
+ 'a'
+ >>> caesar_encipher_letter('z', 2)
+ 'b'
+ >>> caesar_encipher_letter('z', -1)
+ 'y'
+ >>> caesar_encipher_letter('a', -1)
+ 'z'
+ >>> caesar_encipher_letter('A', 1)
+ 'B'
+ >>> caesar_encipher_letter('é', 1)
+ 'f'
+ """
+ # letter = unaccent(accented_letter)
+ # if letter in string.ascii_letters:
+ # if letter in string.ascii_uppercase:
+ # alphabet_start = ord('A')
+ # else:
+ # alphabet_start = ord('a')
+ # return chr(((ord(letter) - alphabet_start + shift) % 26) +
+ # alphabet_start)
+ # else:
+ # return letter
+
+ letter = unaccent(accented_letter)
+ if letter in string.ascii_letters:
+ cipherletter = unpos(pos(letter) + shift)
+ if letter in string.ascii_uppercase:
+ return cipherletter.upper()
+ else:
+ return cipherletter
+ else:
+ return letter
+
+def caesar_decipher_letter(letter, shift):
+ """Decipher a letter, given a shift amount
+
+ >>> caesar_decipher_letter('b', 1)
+ 'a'
+ >>> caesar_decipher_letter('b', 2)
+ 'z'
+ """
+ return caesar_encipher_letter(letter, -shift)
+
+def caesar_encipher(message, shift):
+ """Encipher a message with the Caesar cipher of given shift
+
+ >>> caesar_encipher('abc', 1)
+ 'bcd'
+ >>> caesar_encipher('abc', 2)
+ 'cde'
+ >>> caesar_encipher('abcxyz', 2)
+ 'cdezab'
+ >>> caesar_encipher('ab cx yz', 2)
+ 'cd ez ab'
+ >>> caesar_encipher('Héllo World!', 2)
+ 'Jgnnq Yqtnf!'
+ """
+ enciphered = [caesar_encipher_letter(l, shift) for l in message]
+ return cat(enciphered)
+
+def caesar_decipher(message, shift):
+ """Decipher a message with the Caesar cipher of given shift
+
+ >>> caesar_decipher('bcd', 1)
+ 'abc'
+ >>> caesar_decipher('cde', 2)
+ 'abc'
+ >>> caesar_decipher('cd ez ab', 2)
+ 'ab cx yz'
+ >>> caesar_decipher('Jgnnq Yqtnf!', 2)
+ 'Hello World!'
+ """
+ return caesar_encipher(message, -shift)
+
+
+def caesar_break(message, fitness=Pletters):
+ """Breaks a Caesar cipher using frequency analysis
+
+ It tries all possible keys, scores the fitness of the text decipherd with
+ each key, and returns the key that produces the most fit deciphered text.
+
+ >>> caesar_break('ibxcsyorsaqcheyklxivoexlevmrimwxsfiqevvmihrsasrxliwyrh' \
+ 'ecjsppsamrkwleppfmergefifvmhixscsymjcsyqeoixlm') # doctest: +ELLIPSIS
+ (4, -130.849989015...)
+ >>> caesar_break('wxwmaxdgheetgwuxztgptedbgznitgwwhpguxyhkxbmhvvtlbhgtee' \
+ 'raxlmhiixweblmxgxwmhmaxybkbgztgwztsxwbgmxgmert') # doctest: +ELLIPSIS
+ (19, -128.82410410...)
+ >>> caesar_break('yltbbqnqnzvguvaxurorgenafsbezqvagbnornfgsbevpnaabjurer' \
+ 'svaquvzyvxrnznazlybequrvfohgriraabjtbaruraprur') # doctest: +ELLIPSIS
+ (13, -126.25403935...)
+ """
+ sanitised_message = sanitise(message)
+ best_shift = 0
+ best_fit = float('-inf')
+ for shift in range(26):
+ plaintext = caesar_decipher(sanitised_message, shift)
+ fit = fitness(plaintext)
+
+ if fit > best_fit:
+ best_fit = fit
+ best_shift = shift
+
+ return best_shift, best_fit
+Functions
+-
+
+def caesar_break(message, fitness=<function Pletters>) +
+-
++
Breaks a Caesar cipher using frequency analysis
+It tries all possible keys, scores the fitness of the text decipherd with +each key, and returns the key that produces the most fit deciphered text.
+>>> caesar_break('ibxcsyorsaqcheyklxivoexlevmrimwxsfiqevvmihrsasrxliwyrh' 'ecjsppsamrkwleppfmergefifvmhixscsymjcsyqeoixlm') # doctest: +ELLIPSIS +(4, -130.849989015...) +>>> caesar_break('wxwmaxdgheetgwuxztgptedbgznitgwwhpguxyhkxbmhvvtlbhgtee' 'raxlmhiixweblmxgxwmhmaxybkbgztgwztsxwbgmxgmert') # doctest: +ELLIPSIS +(19, -128.82410410...) +>>> caesar_break('yltbbqnqnzvguvaxurorgenafsbezqvagbnornfgsbevpnaabjurer' 'svaquvzyvxrnznazlybequrvfohgriraabjtbaruraprur') # doctest: +ELLIPSIS +(13, -126.25403935...) +
+++Expand source code +
+
+def caesar_break(message, fitness=Pletters): + """Breaks a Caesar cipher using frequency analysis + + It tries all possible keys, scores the fitness of the text decipherd with + each key, and returns the key that produces the most fit deciphered text. + + >>> caesar_break('ibxcsyorsaqcheyklxivoexlevmrimwxsfiqevvmihrsasrxliwyrh' \ + 'ecjsppsamrkwleppfmergefifvmhixscsymjcsyqeoixlm') # doctest: +ELLIPSIS + (4, -130.849989015...) + >>> caesar_break('wxwmaxdgheetgwuxztgptedbgznitgwwhpguxyhkxbmhvvtlbhgtee' \ + 'raxlmhiixweblmxgxwmhmaxybkbgztgwztsxwbgmxgmert') # doctest: +ELLIPSIS + (19, -128.82410410...) + >>> caesar_break('yltbbqnqnzvguvaxurorgenafsbezqvagbnornfgsbevpnaabjurer' \ + 'svaquvzyvxrnznazlybequrvfohgriraabjtbaruraprur') # doctest: +ELLIPSIS + (13, -126.25403935...) + """ + sanitised_message = sanitise(message) + best_shift = 0 + best_fit = float('-inf') + for shift in range(26): + plaintext = caesar_decipher(sanitised_message, shift) + fit = fitness(plaintext) + + if fit > best_fit: + best_fit = fit + best_shift = shift + + return best_shift, best_fit
+ +def caesar_decipher(message, shift) +
+-
++
Decipher a message with the Caesar cipher of given shift
+>>> caesar_decipher('bcd', 1) +'abc' +>>> caesar_decipher('cde', 2) +'abc' +>>> caesar_decipher('cd ez ab', 2) +'ab cx yz' +>>> caesar_decipher('Jgnnq Yqtnf!', 2) +'Hello World!' +
+++Expand source code +
+
+def caesar_decipher(message, shift): + """Decipher a message with the Caesar cipher of given shift + + >>> caesar_decipher('bcd', 1) + 'abc' + >>> caesar_decipher('cde', 2) + 'abc' + >>> caesar_decipher('cd ez ab', 2) + 'ab cx yz' + >>> caesar_decipher('Jgnnq Yqtnf!', 2) + 'Hello World!' + """ + return caesar_encipher(message, -shift)
+ +def caesar_decipher_letter(letter, shift) +
+-
++
Decipher a letter, given a shift amount
+>>> caesar_decipher_letter('b', 1) +'a' +>>> caesar_decipher_letter('b', 2) +'z' +
+++Expand source code +
+
+def caesar_decipher_letter(letter, shift): + """Decipher a letter, given a shift amount + + >>> caesar_decipher_letter('b', 1) + 'a' + >>> caesar_decipher_letter('b', 2) + 'z' + """ + return caesar_encipher_letter(letter, -shift)
+ +def caesar_encipher(message, shift) +
+-
++
Encipher a message with the Caesar cipher of given shift
+>>> caesar_encipher('abc', 1) +'bcd' +>>> caesar_encipher('abc', 2) +'cde' +>>> caesar_encipher('abcxyz', 2) +'cdezab' +>>> caesar_encipher('ab cx yz', 2) +'cd ez ab' +>>> caesar_encipher('Héllo World!', 2) +'Jgnnq Yqtnf!' +
+++Expand source code +
+
+def caesar_encipher(message, shift): + """Encipher a message with the Caesar cipher of given shift + + >>> caesar_encipher('abc', 1) + 'bcd' + >>> caesar_encipher('abc', 2) + 'cde' + >>> caesar_encipher('abcxyz', 2) + 'cdezab' + >>> caesar_encipher('ab cx yz', 2) + 'cd ez ab' + >>> caesar_encipher('Héllo World!', 2) + 'Jgnnq Yqtnf!' + """ + enciphered = [caesar_encipher_letter(l, shift) for l in message] + return cat(enciphered)
+ +def caesar_encipher_letter(accented_letter, shift) +
+-
++
Encipher a letter, given a shift amount.
+Accented version of latin letters (such as é and ö) are converted to their +non-accented versions before encryption.
+>>> caesar_encipher_letter('a', 1) +'b' +>>> caesar_encipher_letter('a', 2) +'c' +>>> caesar_encipher_letter('b', 2) +'d' +>>> caesar_encipher_letter('x', 2) +'z' +>>> caesar_encipher_letter('y', 2) +'a' +>>> caesar_encipher_letter('z', 2) +'b' +>>> caesar_encipher_letter('z', -1) +'y' +>>> caesar_encipher_letter('a', -1) +'z' +>>> caesar_encipher_letter('A', 1) +'B' +>>> caesar_encipher_letter('é', 1) +'f' +
+++Expand source code +
+
+def caesar_encipher_letter(accented_letter, shift): + """Encipher a letter, given a shift amount. + + Accented version of latin letters (such as é and ö) are converted to their + non-accented versions before encryption. + + >>> caesar_encipher_letter('a', 1) + 'b' + >>> caesar_encipher_letter('a', 2) + 'c' + >>> caesar_encipher_letter('b', 2) + 'd' + >>> caesar_encipher_letter('x', 2) + 'z' + >>> caesar_encipher_letter('y', 2) + 'a' + >>> caesar_encipher_letter('z', 2) + 'b' + >>> caesar_encipher_letter('z', -1) + 'y' + >>> caesar_encipher_letter('a', -1) + 'z' + >>> caesar_encipher_letter('A', 1) + 'B' + >>> caesar_encipher_letter('é', 1) + 'f' + """ + # letter = unaccent(accented_letter) + # if letter in string.ascii_letters: + # if letter in string.ascii_uppercase: + # alphabet_start = ord('A') + # else: + # alphabet_start = ord('a') + # return chr(((ord(letter) - alphabet_start + shift) % 26) + + # alphabet_start) + # else: + # return letter + + letter = unaccent(accented_letter) + if letter in string.ascii_letters: + cipherletter = unpos(pos(letter) + shift) + if letter in string.ascii_uppercase: + return cipherletter.upper() + else: + return cipherletter + else: + return letter
+ +def cat(iterable, /) +
+-
++
Concatenate any number of strings.
+The string whose method is called is inserted in between each given string. +The result is returned as a new string.
+Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs'
+ +def lcat(iterable, /) +
+-
++
Concatenate any number of strings.
+The string whose method is called is inserted in between each given string. +The result is returned as a new string.
+Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs'
+ +def wcat(iterable, /) +
+-
++
Concatenate any number of strings.
+The string whose method is called is inserted in between each given string. +The result is returned as a new string.
+Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs'
+