+def transpositions_of(keyword):
+ """Finds the transpostions given by a keyword. For instance, the keyword
+ 'clever' rearranges to 'celrv', so the first column (0) stays first, the
+ second column (1) moves to third, the third column (2) moves to second,
+ and so on.
+
+ >>> transpositions_of('clever')
+ [0, 2, 1, 4, 3]
+ """
+ key = deduplicate(keyword)
+ transpositions = [key.index(l) for l in sorted(key)]
+ return transpositions
+
+def column_transposition_encipher(message, keyword, fillvalue=' '):
+ """Enciphers using the column transposition cipher.
+ Message is padded to allow all rows to be the same length.
+
+ >>> column_transposition_encipher('hellothere', 'clever')
+ 'hleolteher'
+ >>> column_transposition_encipher('hellothere', 'cleverly', fillvalue='!')
+ 'hleolthre!e!'
+ """
+ return column_transposition_worker(message, keyword, encipher=True,
+ fillvalue=fillvalue)
+
+def column_transposition_decipher(message, keyword, fillvalue=' '):
+ """Deciphers using the column transposition cipher.
+ Message is padded to allow all rows to be the same length.
+
+ >>> column_transposition_decipher('hleolteher', 'clever')
+ '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)
+ 'hellothere'
+ """
+ transpositions = transpositions_of(keyword)
+ columns = every_nth(message, len(transpositions), fillvalue=fillvalue)
+ if encipher:
+ transposed_columns = transpose(columns, transpositions)
+ else:
+ transposed_columns = untranspose(columns, transpositions)
+ return combine_every_nth(transposed_columns)
+
+
+