Skip to content

Commit

Permalink
Final documentation of project 1
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian Kiær authored and Christian Kiær committed Jun 27, 2013
1 parent 62da672 commit 146c9bc
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 24 deletions.
5 changes: 4 additions & 1 deletion project1/FreqAnalysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
import os

if __name__ == '__main__':
"""Tool for analysing an input text, and outputting a frequency
analysis of mono/dia/trigrams in a given input text. Takes the input file and runs through it, saving the
ammount of times a character and dia/trigrams is present. Then outputs the given values to 2 .txt files.
If a british english text is given as a input file, a representation close to the frequency of letters of the english alphabet should be outputtet."""
os.system('clear')

# Check if enough argument were given
Expand All @@ -10,7 +14,6 @@
argcount += 1
if argcount < 2:
print "Error: No input file spesified"
exit()

script, inputfile = argv

Expand Down
52 changes: 34 additions & 18 deletions project1/ManualSubCipherTool.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@


def decryption(cipher):
"""Decrypt ciphertext"""
"""Menu for assisting in decryption of ciphertext.
Gives you possibilities for assigning plaintext letters to ciphertext letters,
unassign letters in plaintext and display most frequent mono/dia/tri"""
found = False

cip = list(cipher)
Expand Down Expand Up @@ -54,22 +56,29 @@ def decryption(cipher):
os.system('clear')

def assignPlainToCipher(cip, plaintext):
"""Assign plaintext character to corresponding ciphertext character"""
"""Assign plaintext character to corresponding ciphertext character.
First input to console is the ciphertext letter you want to assign a new letter to.
Second input is the plaintext letter you want to assign to a ciphertext letter.
Then loops over entire cipher change every character."""
keyToChange = str(raw_input("What cipher do you want to assign a plain character? ")).upper()
keyChanged = str(raw_input("What letter do you want to input? ")).lower()
for x in range(0, len(cip)):
if cip[x] == keyToChange:
plaintext[x] = keyChanged

def unasignPlain(plaintext):
"""Unassign previous assigned plaintext to ciphertext"""
"""Unassign previous assigned plaintext to ciphertext
Input the plaintext character you want to unasign.
Loops through entire plaintext to remove every character."""
keyToChange = str(raw_input("What plaintext character do you want to unassign? ")).lower()
for x in range(0, len(plaintext)):
if plaintext[x] == keyToChange:
plaintext[x] = '-'

def right_input(i):
"""Get input from user and validate"""
"""Get input from user and validate.
Function to make sure the right input is given.
Right inputs is between 0 and the given i. Gives user another try if wrong key is pressed"""
while True:
x = raw_input("Please enter a value: ")
try:
Expand All @@ -83,19 +92,21 @@ def right_input(i):
return x

def remove_space(plaintext, cip):
"""Remove whitespaces from ciphertext"""
"""Remove whitespaces from ciphertext. Loops over the ciphertext
and sets corresponding plaintext position as whitespace."""
for x in xrange(0,len(cip)):
if cip[x] == ' ':
plaintext[x] = ' '


def display_diagrams(cip):
"""Display dia and trigram frequencies in given ciphertext and compare to the given language's"""
"""Display dia and trigram frequencies in given ciphertext and compare to the given language's.
Opens the output2.txt from created from the FreqAnalysis tool. Runs through the cipher text
storing dia/trigrams in a dictonary. The ammount of appearances and the tri/diagram is then saved and printed.
Then prints the most frequent dia/trigams from the english language"""
input_grams = open("output2.txt", "r")

print "Ciphers frequency of dia/trigrams:"

print "Ciphers frequency of letters:"

dict = {}

Expand Down Expand Up @@ -124,7 +135,10 @@ def display_diagrams(cip):
input_grams.close()

def display_letter(cip):
"""Display letter frequencies in given ciphertext and compare to the given language's"""
"""Display letter frequencies in given ciphertext and compare to the given language's
Opens the output1.txt generated from the FreqAnalysis tool. Runs through the cipher text and stores each letter and the ammount of times
it's present in the text. Prints the character and corresponding ammount. Then outputs the frequencies of the english language
from output2.txt"""
input_frequency = open("output1.txt", "r")

dict = {}
Expand All @@ -151,19 +165,21 @@ def display_letter(cip):
input_frequency.close()

if __name__ == '__main__':
os.system('clear')
"""Tool for manual assitance in decryption of a substitution ciphertext.
Possible to get analysis of both ciphertext and from the english language"""
os.system('clear')

script, cipher = argv
script, cipher = argv

print "Hello! \nWelcome to our decryption assistance tool! How may I help you?"
print "1) Decrypt"
print "0) Exit"
print "Hello! \nWelcome to our decryption assistance tool! How may I help you?"
print "1) Decrypt"
print "0) Exit"

keyPressed = int(right_input(1))
keyPressed = int(right_input(1))

if keyPressed == 0:
if keyPressed == 0:
exit
elif keyPressed == 1:
elif keyPressed == 1:
decryption(cipher.upper())
else:
else:
print "Exiting"
67 changes: 62 additions & 5 deletions project1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ Consists of two Python scripts:
* **ManualSubCipherTool.py**: Helps to manually decrypt a given
cipher by showing frequency analysis and comparing to the output
for the previous mentioned script.


*NOTE:* Written in markdown. Open in browser to have good support.
## Usage

### FreqAnalysis
Expand All @@ -29,23 +30,79 @@ The output will then be stored in two files:

1. `output1.txt`: Letter frequencies
2. `output2.txt`: Dia- and trigram frequencies

Docstrings is inserted for offical Python documentation.

*NOTE:* Out of the box contains `input.txt` a sample English text by
[Project Gutenberg](www.gutenberg.org).
[Project Gutenberg](www.gutenberg.org). Given another input text, the
output frequencies will be different.

### ManualSubCipherTool

With a given ciphertext, `CyPhErTeXt`, run the script with:
Uses a ciphertext as input. Run with:

python ManualSubCipherTool.py "CyPhErTeXt"

Where "CyPhErTeXt" is the substituted cipher text.

You will now be prompted with an interactive command line interface
where you can select options with the number keys on the you keyboard.
You will now be prompted with an interactive command line interface.
It will be possible to navigate through with keyboard commands as input.

The tool uses the output from the FreqAnalysis tool for showing
frequencies of mono/dia/trigrams.

Docstrings is inserted for offical Python documentation.

*NOTE:* As noted under FreqAnalysis, it comes with a sample English
word analysis. If your ciphertext is of a different language, you
will have to run the FreqAnalysis tool of text in the wanted language.


## Logic behind.

The FreqAnalysis tool is based on an input .txt file. It the uses the following:

1. Input text is loaded
2. The tool runs through the input text, saving all characters/dia/trigrams and the ammount of times they have been spotted.
3. Outputs two .txt files containing, one containing the frequencies of letters and one containing frequencies of dia/trigrams in the text.

The ManualSubCipherTool is based around assistance in decryption of a cipher text. It follows this order:

1. The tool is started with a input cipher.
2. 5 Possibilities are given:
1. Assign a plaintext letter to a ciphertext letter.
2. Unassign a plaintext letter.
3. Display frequencies of letters in cipher/english language.
4. Display frequencies of dia/trigrams in cipher/english language.
5. Finish your decryption
3. This is repeated untill you find the desired plaintext.

The following snippet of code is the corner stone of the two tools, wich gives us the frequencies of mono/dia/trigrams in our cipher and the english language:

#Itereate lines in input file
for line in input:
line = line.upper() # Clean line

# For every leagal permutation
for i in xrange(0, len(line)):
# Mono-, dia- and trigrams
for j in xrange(1, 4):
ch = line[i:i+j] # Substring w/ *gram

# Continue if not all letters
if not ch.isalpha(): continue

# Lazy create and inc counter
if ch in dict:
dict[ch] += 1
else:
dict[ch] = 1

# Increment total number of *grams
count[0 if len(ch) < 2 else 1] += 1

It lets us assign mono/dia/trigrams in a HashTable and assign the value as the ammount of times they have been checked.

## Further Help

For further help or explanation please contact one of us by mail and
Expand Down

0 comments on commit 146c9bc

Please sign in to comment.