From 2a81bfe6423fb8500413c01a2e9fc5ea4997b581 Mon Sep 17 00:00:00 2001 From: Pocholo Date: Sun, 19 Jul 2020 02:00:12 +0800 Subject: [PATCH] docs: update docs --- classicrack/ciphers/affine.py | 32 +++++++++++++++++++++++--------- classicrack/ciphers/atbash.py | 14 ++++++++------ classicrack/ciphers/caesar.py | 18 ++++++++++-------- classicrack/ciphers/rot13.py | 12 ++++++++---- docs/source/conf.py | 13 ++++++++++--- docs/source/index.rst | 35 ++++++++++++++++++++++++++++++++--- 6 files changed, 91 insertions(+), 33 deletions(-) diff --git a/classicrack/ciphers/affine.py b/classicrack/ciphers/affine.py index 2f5093f..c534b1e 100644 --- a/classicrack/ciphers/affine.py +++ b/classicrack/ciphers/affine.py @@ -3,6 +3,17 @@ from classicrack.ngrams.monograms import monograms class Affine: + """ + Affine cipher is a monoalphabetic substitution cipher + that uses the following encryption function:: + + E(x) = (ax + b) mod m + + It is decrypted by taking the modular multiplicative + inverse ``inv`` of the slope value ``a``:: + + D(x) = inv * (x - b) mod m + """ # check if slope is coprime with 26 def coprime(self, slope: int): @@ -18,9 +29,10 @@ def get_inverse(self, slope: int): def encode(self, text: str, slope: int, intercept: int): """ Enciphers an input plaintext using Affine Cipher. - text (str): input plaintext - slope (int): slope value (must be coprime with 26) - intercept (int): intercept value + + :param text: input plaintext + :param slope: slope value, which must be coprime with 26 + :param intercept: intercept value """ if not self.coprime(slope): raise ValueError('slope is not coprime with 26') x = order_chars(parse_text(text)) @@ -30,9 +42,10 @@ def encode(self, text: str, slope: int, intercept: int): def decode(self, text: str, slope: int, intercept: int): """ Deciphers an input Affine ciphertext. - text (str): input ciphertext - slope (int): slope value (must be coprime with 26) - intercept (int): intercept value + + :param text: input ciphertext + :param slope: slope value, which must be coprime with 26 + :param intercept: intercept value """ inv = self.get_inverse(slope) x = order_chars(parse_text(text)) @@ -41,9 +54,10 @@ def decode(self, text: str, slope: int, intercept: int): def crack(self, text: str): """ - Cracks an input Affine ciphertext, and returns - plaintext values with acceptable fitness scores. - text (str): input ciphertext + Cracks an input Affine ciphertext by generating all 312 possible values, + and returns plaintext values with acceptable fitness scores. + + :param text: input ciphertext """ print("Cracking...\n") diff --git a/classicrack/ciphers/atbash.py b/classicrack/ciphers/atbash.py index 391c18c..7d7ad10 100644 --- a/classicrack/ciphers/atbash.py +++ b/classicrack/ciphers/atbash.py @@ -2,16 +2,17 @@ class Atbash: """ - Atbash implementation. - >>> ab = Atbash() - >>> ab.encode('zebras') - >>> ab.decode('avyizh') + Atbash is a monoalphabetic substitution cipher that is similar to Affine Cipher. + Unlike Affine, Atbash takes the following function for encryption and decryption:: + + E(x) = D(x) = (-x mod m) + 1 """ def encode(self, text: str): """ Encipher an input plaintext using Atbash. - text (str): input text + + :param text: input plaintext """ text = parse_text(text) out = [chr(122 - ord(text[i]) + 97) for i in range(len(text))] @@ -20,7 +21,8 @@ def encode(self, text: str): def decode(self, text: str): """ Decipher an input Atbash ciphertext. - text (str): input text + + :param text: input ciphertext """ text = parse_text(text) out = [chr(122 - ord(text[i]) + 97) for i in range(len(text))] diff --git a/classicrack/ciphers/caesar.py b/classicrack/ciphers/caesar.py index b632d8d..73c0d1c 100644 --- a/classicrack/ciphers/caesar.py +++ b/classicrack/ciphers/caesar.py @@ -5,24 +5,25 @@ class Caesar: """ - Caesar Cipher Implementation. - >>> cs = Caesar() - >>> cs.encode('purrzfoheztre') + Caesar Cipher is a monoalphabetic substitution cipher where + characters are shifted with a fixed shift value of ``n mod 26``. """ def encode(self, text: str, shift: int): """ Enciphers an input plaintext using Caesar. - text (str): input plaintext - shift (int): shift value + + :param text: input plaintext + :param shift: shift value """ return shift_mono(parse_text(text), shift) def decode(self, text: str, shift: int): """ Deciphers an input Caesar ciphertext. - text (str): input plaintext - shift (int): shift value + + :param text: input ciphertext + :param shift: shift value """ return shift_mono(parse_text(text), shift, decode=True) @@ -30,7 +31,8 @@ def crack(self, text: str): """ Cracks an input Caesar ciphertext and returns plaintext values with acceptable fitness scores. - text (str): input plaintext + + :param text: input plaintext """ print("Cracking...\n") ctxts = [shift_mono(text, x, decode=True) for x in range(26)] diff --git a/classicrack/ciphers/rot13.py b/classicrack/ciphers/rot13.py index a21ab76..ed534eb 100644 --- a/classicrack/ciphers/rot13.py +++ b/classicrack/ciphers/rot13.py @@ -2,20 +2,24 @@ class ROT13: """ - ROT13 Implementation. - >>> rot = ROT13() - >>> rot.encode('cheemsburmger') - >>> rot.decode('purrzfoheztre') + ROT13 is similar to Caesar Cipher, where each character takes a shift value of 13:: + + ABCDEFGHIJKLMNOPQRSTUVWXYZ + NOPQRSTUVWXYZABCDEFGHIJKLM """ def encode(self, text: str): """ Encipher an input plaintext using ROT-13. + + :param text: input plaintext """ return shift_mono(parse_text(text), 13) def decode(self, text: str): """ Decipher an input ROT-13 ciphertext. + + :param text: input ciphertext """ return shift_mono(parse_text(text), 13) \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index e17e083..5243712 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -14,6 +14,7 @@ # import sys # sys.path.insert(0, os.path.abspath('.')) +import sphinx_rtd_theme # -- Project information ----------------------------------------------------- @@ -27,8 +28,7 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = [ -] +extensions = ['sphinx.ext.autodoc', 'sphinx_rtd_theme'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -46,7 +46,14 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'alabaster' +html_theme = 'sphinx_rtd_theme' + +html_context = { + 'display_github': True, + 'github_user': 'starkfire', + 'github_repo': 'classicrack', + 'github_version': 'master/docs/source/' +} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, diff --git a/docs/source/index.rst b/docs/source/index.rst index 0596177..bd3a611 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -18,14 +18,16 @@ Python library for implementing and performing cryptanalysis on classical cipher Supported Ciphers ----------------- -* Affine (no stable cracking implementation yet) +* Affine * Atbash * Caesar * ROT13 Cryptanalysis ------------- -So far, the project can only perform cryptanalysis on supported ciphers, and only works when the cipher used is known. It does not yet include modules for discerning what cipher is used in a text. +For cracking, cipher implementations have a ``crack()`` method. Implementations of some ciphers, such as ROT-13 and Atbash do not have it, since the ``decode()`` method already performs the same task. + +So far, classicrack can only perform cryptanalysis on ciphers with keyspace weaknesses (e.g. Affine, Caesar). Implementations for other ciphers such as Vigenere might be added soon. Install ------- @@ -35,4 +37,31 @@ Clone the project on GitHub and install with pip: git clone https://github.com/starkfire/classicrack/ cd classicrack/ - pip install -r requirements.txt \ No newline at end of file + pip install -r requirements.txt + +Ciphers +======= + +Affine +------ + +.. autoclass:: classicrack.ciphers.Affine + :members: + +Caesar +------ + +.. autoclass:: classicrack.ciphers.Caesar + :members: + +Atbash +------ + +.. autoclass:: classicrack.ciphers.Atbash + :members: + +ROT13 +----- + +.. autoclass:: classicrack.ciphers.ROT13 + :members: \ No newline at end of file