import string
import collections
-# import norms
import logging
-# import math
-from itertools import zip_longest, repeat, cycle
-# from segment import segment
-# from multiprocessing import Pool
+from itertools import zip_longest, cycle
logger = logging.getLogger(__name__)
return ''.join([''.join(l)
for l in zip_longest(*split_text, fillvalue='')])
+def chunks(text, n, fillvalue=None):
+ """Split a text into chunks of n characters
+
+ >>> chunks('abcdefghi', 3)
+ ['abc', 'def', 'ghi']
+ >>> chunks('abcdefghi', 4)
+ ['abcd', 'efgh', 'i']
+ >>> chunks('abcdefghi', 4, fillvalue='!')
+ ['abcd', 'efgh', 'i!!!']
+ """
+ if fillvalue:
+ padding = fillvalue[0] * (n - len(text) % n)
+ else:
+ padding = ''
+ return [(text+padding)[i:i+n] for i in range(0, len(text), n)]
+
def transpose(items, transposition):
"""Moves items around according to the given transposition
>>> transpose([10,11,12,13,14,15], (3,2,4,1,5,0))
[13, 12, 14, 11, 15, 10]
"""
- transposed = list(repeat('', len(transposition)))
+ transposed = [''] * len(transposition)
for p, t in enumerate(transposition):
transposed[p] = items[t]
return transposed
>>> untranspose([13, 12, 14, 11, 15, 10], [3,2,4,1,5,0])
[10, 11, 12, 13, 14, 15]
"""
- transposed = list(repeat('', len(transposition)))
+ transposed = [''] * len(transposition)
for p, t in enumerate(transposition):
transposed[t] = items[p]
return transposed
-
-
def deduplicate(text):
return list(collections.OrderedDict.fromkeys(text))
-
def caesar_encipher_letter(letter, shift):
"""Encipher a letter, given a shift amount
transpositions = tuple(key.index(l) for l in sorted(key))
return transpositions
-def column_transposition_encipher(message, keyword, fillvalue=' '):
+def column_transposition_encipher(message, keyword, fillvalue=' ',
+ columnwise=False):
"""Enciphers using the column transposition cipher.
Message is padded to allow all rows to be the same length.
'hleolteher'
>>> column_transposition_encipher('hellothere', 'cleverly', fillvalue='!')
'hleolthre!e!'
+ >>> column_transposition_encipher('hellothere', 'clever', columnwise=True)
+ 'htleehoelr'
"""
- return column_transposition_worker(message, keyword, encipher=True,
- fillvalue=fillvalue)
+ transpositions = transpositions_of(keyword)
+ columns = every_nth(message, len(transpositions), fillvalue=fillvalue)
+ transposed_columns = transpose(columns, transpositions)
+ if columnwise:
+ return ''.join(transposed_columns)
+ else:
+ return combine_every_nth(transposed_columns)
-def column_transposition_decipher(message, keyword, fillvalue=' '):
+def column_transposition_decipher(message, keyword, fillvalue=' ',
+ columnwise=False):
"""Deciphers using the column transposition cipher.
Message is padded to allow all rows to be the same length.
'hellothere'
>>> column_transposition_decipher('hleolthre!e!', 'cleverly', fillvalue='?')
'hellothere!!'
- """
- return column_transposition_worker(message, keyword, encipher=False,
- fillvalue=fillvalue)
-
-def column_transposition_worker(message, keyword,
- encipher=True, fillvalue=' '):
- """Does the actual work of the column transposition cipher.
- Message is padded with spaces to allow all rows to be the same length.
-
- >>> column_transposition_worker('hellothere', 'clever')
- 'hleolteher'
- >>> column_transposition_worker('hellothere', 'clever', encipher=True)
- 'hleolteher'
- >>> column_transposition_worker('hleolteher', 'clever', encipher=False)
+ >>> column_transposition_decipher('htleehoelr', 'clever', columnwise=True)
'hellothere'
"""
transpositions = transpositions_of(keyword)
- columns = every_nth(message, len(transpositions), fillvalue=fillvalue)
- if encipher:
- transposed_columns = transpose(columns, transpositions)
+ if columnwise:
+ columns = chunks(message, int(len(message) / len(transpositions)))
else:
- transposed_columns = untranspose(columns, transpositions)
- return combine_every_nth(transposed_columns)
+ columns = every_nth(message, len(transpositions), fillvalue=fillvalue)
+ untransposed_columns = untranspose(columns, transpositions)
+ return combine_every_nth(untransposed_columns)
+
def vigenere_encipher(message, keyword):
"""Vigenere encipher
pairs = zip(message, cycle(shifts))
return ''.join([caesar_decipher_letter(l, k) for l, k in pairs])
+beaufort_encipher=vigenere_decipher
+beaufort_decipher=vigenere_encipher
if __name__ == "__main__":