X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=cipher.py;h=a511e2492667dfa4abad4ada7f15d67a4aa30d75;hb=07c3f8b652e218c94ad2a0dd1fb4657be4c6fe17;hp=d2438b720693c6abc231b827fe26a8d5ce52dddf;hpb=77806680e76ebff49b16383e58feedaf22750eb2;p=cipher-training.git diff --git a/cipher.py b/cipher.py index d2438b7..a511e24 100644 --- a/cipher.py +++ b/cipher.py @@ -5,7 +5,6 @@ them. See cipherbreak for automatic breaking of these ciphers import string import collections from enum import Enum -from itertools import zip_longest, cycle, chain from language_models import unaccent, sanitise @@ -16,52 +15,6 @@ for a in range(26): modular_division_table[b][c] = a -def every_nth(text, n, fillvalue=''): - """Returns n strings, each of which consists of every nth character, - starting with the 0th, 1st, 2nd, ... (n-1)th character - - >>> every_nth(string.ascii_lowercase, 5) - ['afkpuz', 'bglqv', 'chmrw', 'dinsx', 'ejoty'] - >>> every_nth(string.ascii_lowercase, 1) - ['abcdefghijklmnopqrstuvwxyz'] - >>> every_nth(string.ascii_lowercase, 26) # doctest: +NORMALIZE_WHITESPACE - ['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'] - >>> every_nth(string.ascii_lowercase, 5, fillvalue='!') - ['afkpuz', 'bglqv!', 'chmrw!', 'dinsx!', 'ejoty!'] - """ - split_text = chunks(text, n, fillvalue) - return [''.join(l) for l in zip_longest(*split_text, fillvalue=fillvalue)] - -def combine_every_nth(split_text): - """Reforms a text split into every_nth strings - - >>> combine_every_nth(every_nth(string.ascii_lowercase, 5)) - 'abcdefghijklmnopqrstuvwxyz' - >>> combine_every_nth(every_nth(string.ascii_lowercase, 1)) - 'abcdefghijklmnopqrstuvwxyz' - >>> combine_every_nth(every_nth(string.ascii_lowercase, 26)) - 'abcdefghijklmnopqrstuvwxyz' - """ - 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 deduplicate(text): """If a string contains duplicate letters, remove all but the first. Retain the order of the letters. @@ -308,31 +261,6 @@ def keyword_decipher(message, keyword, cipher_translation = ''.maketrans(cipher_alphabet, string.ascii_lowercase) return message.lower().translate(cipher_translation) - -def vigenere_encipher(message, keyword): - """Vigenere encipher - - >>> vigenere_encipher('hello', 'abc') - 'hfnlp' - """ - shifts = [ord(l) - ord('a') for l in sanitise(keyword)] - pairs = zip(message, cycle(shifts)) - return ''.join([caesar_encipher_letter(l, k) for l, k in pairs]) - -def vigenere_decipher(message, keyword): - """Vigenere decipher - - >>> vigenere_decipher('hfnlp', 'abc') - 'hello' - """ - shifts = [ord(l) - ord('a') for l in sanitise(keyword)] - 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__": import doctest doctest.testmod()