Skip to content

Commit

Permalink
docs: update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
starkfire committed Jul 18, 2020
1 parent 67a5e67 commit 2a81bfe
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 33 deletions.
32 changes: 23 additions & 9 deletions classicrack/ciphers/affine.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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))
Expand All @@ -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))
Expand All @@ -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")

Expand Down
14 changes: 8 additions & 6 deletions classicrack/ciphers/atbash.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))]
Expand All @@ -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))]
Expand Down
18 changes: 10 additions & 8 deletions classicrack/ciphers/caesar.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,34 @@

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)

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)]
Expand Down
12 changes: 8 additions & 4 deletions classicrack/ciphers/rot13.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
13 changes: 10 additions & 3 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# import sys
# sys.path.insert(0, os.path.abspath('.'))

import sphinx_rtd_theme

# -- Project information -----------------------------------------------------

Expand All @@ -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']
Expand All @@ -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,
Expand Down
35 changes: 32 additions & 3 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------
Expand All @@ -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
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:

0 comments on commit 2a81bfe

Please sign in to comment.