physics, maths & computer science

Use of dictionaries throughout, to preserve the key I converted to JSON, which easy to read into python script

import random
import json
plaintext = raw_input("enter plaintext to encipher: ")

enter plaintext to encipher: Hello World

create the key
letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
frequencies = [8.2,1.5,2.8,4.3,12.7,2.2,2.0,6.1,7.0,0.2,0.8,4.0,2.4,6.7,7.5,1.9,0.1,6.0,6.3,9.1,2.8,1.0,2.4,0.2,2.0,0.1]

NOTE: frequencies taken from ‘Code, Simon Singh’

def round_up(x):
x = int(round(x))
if x == 0:
x = 1
if x >=8:
x = x -1
return x

frequencies = map(round_up, frequencies)
homophone_list = [num for num in range(0,100,1)]
alphabet = [chr(num+97).upper() for num in range(0,26,1)]
frequencies_dict = dict(zip(alphabet,frequencies))

select random choice from the homophone dictionary for each letter to substitute
for k,v in frequencies_dict.iteritems():
letter_homophones = []
i = 0
while i < v:
selection = random.choice(homophone_list)
letter_homophones.append(selection)
homophone_list.remove(selection)
i += 1
frequencies_dict[k] = letter_homophones

make the substitution

plaintext = plaintext.upper()
plaintext = plaintext.replace(' ','')
ciphertext = ''
for letter in plaintext:
cipher_selection = frequencies_dict[letter]
cipher_choice = random.choice(cipher_selection)
if cipher_choice < 10:
cipher_choice = str(cipher_choice)
cipher_choice = '0'+cipher_choice
else:
cipher_choice = str(cipher_choice)
ciphertext = ciphertext+cipher_choice
print "ciphertext is: ",ciphertext
print "key is: ",frequencies_dict

gives:
ciphertext is: 04737433145702543323
key is: {‘A’: [10, 66, 19, 86, 59, 95, 85], ‘C’: [93, 17, 47], ‘B’: [31, 81], ‘E’: [79, 27, 46, 41, 70, 88, 60, 87, 73, 65, 69, 55], ‘D’: [23, 72, 99, 48], ‘G’: [38, 24], ‘F’: [30, 76], ‘I’: [13, 45, 52, 68, 78, 1, 43], ‘H’: [82, 4, 29, 9, 80, 26], ‘K’: [98], ‘J’: [25], ‘M’: [50, 91], ‘L’: [44, 62, 74, 33], ‘O’: [96, 16, 2, 37, 14, 36, 34], ‘N’: [71, 35, 49, 15, 61, 97, 90], ‘Q’: [3], ‘P’: [42, 51], ‘S’: [67, 18, 75, 12, 64, 20], ‘R’: [56, 8, 63, 54, 39, 22], ‘U’: [0, 11, 28], ‘T’: [92, 6, 89, 21, 32, 94, 7, 84], ‘W’: [57, 53], ‘V’: [40], ‘Y’: [77, 83], ‘X’: [58], ‘Z’: [5]}

preserve the key (ipython magic)
%%writefile C:/Users/HP/Desktop/key.txt

Store python dictionary as human-readable JSON format
json.dump(frequencies_dict, open('C:/Users/HP/Desktop/key.txt','w'))

to decipher:

ciphertext = str(raw_input("enter ciphertext: "))

import key if necessary
frequencies_dict = json.load(open('C:/Users/HP/Desktop/key.txt'))
cipher_letters = []
i = 0
while i<len(ciphertext):
component_1 = ciphertext[i]
component_2 = ciphertext[i+1]
if component_1[0] == '0':
cipher_letter = component_2
else:
cipher_letter = component_1 + component_2
cipher_letters.append(cipher_letter)
i += 2

plaintext = ''
for cipher_letter in cipher_letters:
for k,v in frequencies_dict.iteritems():
if int(cipher_letter) in v:
plaintext = plaintext+k
plaintext = plaintext.lower()
print 'plaintext is: ',plaintext

gives:
plaintext is: helloworld