X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=docs%2Fszyfrow%2Fcaesar.html;fp=docs%2Fszyfrow%2Fcaesar.html;h=2f40c00113d8556cee8adb5d5fbb57704b55134c;hb=b535d9d75e69cc395e8de28c99e38564655e5ac9;hp=0000000000000000000000000000000000000000;hpb=f19a021eabb3222709b9d513839a14c01cfdfd38;p=szyfrow.git diff --git a/docs/szyfrow/caesar.html b/docs/szyfrow/caesar.html new file mode 100644 index 0000000..2f40c00 --- /dev/null +++ b/docs/szyfrow/caesar.html @@ -0,0 +1,461 @@ + + + + + + +szyfrow.caesar API documentation + + + + + + + + + + + +
+
+
+

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'

+
+
+
+
+
+
+ +
+ + + \ No newline at end of file