1 from utilities
import *
2 from language_models
import *
3 from itertools
import chain
5 from logger
import logger
7 def make_cadenus_keycolumn(doubled_letters
= 'vw', start
='a', reverse
=False):
8 """Makes the key column for a Cadenus cipher (the column down between the
11 >>> make_cadenus_keycolumn()['a']
13 >>> make_cadenus_keycolumn()['b']
15 >>> make_cadenus_keycolumn()['c']
17 >>> make_cadenus_keycolumn()['v']
19 >>> make_cadenus_keycolumn()['w']
21 >>> make_cadenus_keycolumn()['z']
23 >>> make_cadenus_keycolumn(doubled_letters='ij', start='b', reverse=True)['a']
25 >>> make_cadenus_keycolumn(doubled_letters='ij', start='b', reverse=True)['b']
27 >>> make_cadenus_keycolumn(doubled_letters='ij', start='b', reverse=True)['c']
29 >>> make_cadenus_keycolumn(doubled_letters='ij', start='b', reverse=True)['i']
31 >>> make_cadenus_keycolumn(doubled_letters='ij', start='b', reverse=True)['j']
33 >>> make_cadenus_keycolumn(doubled_letters='ij', start='b', reverse=True)['v']
35 >>> make_cadenus_keycolumn(doubled_letters='ij', start='b', reverse=True)['z']
38 index_to_remove
= string
.ascii_lowercase
.find(doubled_letters
[0])
39 short_alphabet
= string
.ascii_lowercase
[:index_to_remove
] + string
.ascii_lowercase
[index_to_remove
+1:]
41 short_alphabet
= cat(reversed(short_alphabet
))
42 start_pos
= short_alphabet
.find(start
)
43 rotated_alphabet
= short_alphabet
[start_pos
:] + short_alphabet
[:start_pos
]
44 keycolumn
= {l
: i
for i
, l
in enumerate(rotated_alphabet
)}
45 keycolumn
[doubled_letters
[0]] = keycolumn
[doubled_letters
[1]]
48 def cadenus_encipher(message
, keyword
, keycolumn
, fillvalue
='a'):
49 """Encipher with the Cadenus cipher
51 >>> cadenus_encipher(sanitise('Whoever has made a voyage up the Hudson ' \
52 'must remember the Kaatskill mountains. ' \
53 'They are a dismembered branch of the great'), \
55 make_cadenus_keycolumn(doubled_letters='vw', start='a', reverse=True))
56 'antodeleeeuhrsidrbhmhdrrhnimefmthgeaetakseomehetyaasuvoyegrastmmuuaeenabbtpchehtarorikswosmvaleatned'
57 >>> cadenus_encipher(sanitise('a severe limitation on the usefulness of ' \
58 'the cadenus is that every message must be ' \
59 'a multiple of twenty-five letters long'), \
61 make_cadenus_keycolumn(doubled_letters='vw', start='a', reverse=True))
62 'systretomtattlusoatleeesfiyheasdfnmschbhneuvsnpmtofarenuseieeieltarlmentieetogevesitfaisltngeeuvowul'
64 rows
= chunks(message
, len(message
) // 25, fillvalue
=fillvalue
)
66 rotated_columns
= [col
[start
:] + col
[:start
] for start
, col
in zip([keycolumn
[l
] for l
in keyword
], columns
)]
67 rotated_rows
= zip(*rotated_columns
)
68 transpositions
= transpositions_of(keyword
)
69 transposed
= [transpose(r
, transpositions
) for r
in rotated_rows
]
70 return cat(chain(*transposed
))
72 def cadenus_decipher(message
, keyword
, keycolumn
, fillvalue
='a'):
74 >>> cadenus_decipher('antodeleeeuhrsidrbhmhdrrhnimefmthgeaetakseomehetyaa' \
75 'suvoyegrastmmuuaeenabbtpchehtarorikswosmvaleatned', \
77 make_cadenus_keycolumn(reverse=True))
78 'whoeverhasmadeavoyageupthehudsonmustrememberthekaatskillmountainstheyareadismemberedbranchofthegreat'
79 >>> cadenus_decipher('systretomtattlusoatleeesfiyheasdfnmschbhneuvsnpmtof' \
80 'arenuseieeieltarlmentieetogevesitfaisltngeeuvowul', \
82 make_cadenus_keycolumn(reverse=True))
83 'aseverelimitationontheusefulnessofthecadenusisthateverymessagemustbeamultipleoftwentyfiveletterslong'
85 rows
= chunks(message
, len(message
) // 25, fillvalue
=fillvalue
)
86 transpositions
= transpositions_of(keyword
)
87 untransposed_rows
= [untranspose(r
, transpositions
) for r
in rows
]
88 columns
= zip(*untransposed_rows
)
89 rotated_columns
= [col
[-start
:] + col
[:-start
] for start
, col
in zip([keycolumn
[l
] for l
in keyword
], columns
)]
90 rotated_rows
= zip(*rotated_columns
)
91 # return rotated_columns
92 return cat(chain(*rotated_rows
))
94 if __name__
== "__main__":