X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;ds=sidebyside;f=cipher.py;h=273da4681040feff53f28d7fcee21ff22ad1a923;hb=38f3707a2337652adf616b47b2f35f3f20d433bd;hp=ebba6d622c5c182b604dcef27fe92aa34565667c;hpb=c50c0b62ecdf5138d6c4b3677aba8035c8481f0c;p=cipher-tools.git diff --git a/cipher.py b/cipher.py index ebba6d6..273da46 100644 --- a/cipher.py +++ b/cipher.py @@ -2,6 +2,7 @@ import string import collections import norms import logging +from itertools import zip_longest from segment import segment # To time a run: @@ -61,6 +62,33 @@ def ngrams(text, n): """ return [tuple(text[i:i+n]) for i in range(len(text)-n+1)] +def every_nth(text, n): + """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) + ['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'] + """ + split_text = [text[i:i+n] for i in range(0, len(text), n)] + return [''.join(l) for l in zip_longest(*split_text, 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 letter_frequencies(text): """Count the number of occurrences of each character in text @@ -166,7 +194,6 @@ def affine_encipher_letter(letter, multiplier=1, adder=0, one_based=True): if one_based: letter_number += 1 raw_cipher_number = (letter_number * multiplier + adder) - cipher_number = 0 if one_based: cipher_number = (raw_cipher_number - 1) % 26 else: @@ -189,13 +216,9 @@ def affine_decipher_letter(letter, multiplier=1, adder=0, one_based=True): else: alphabet_start = ord('a') cipher_number = ord(letter) - alphabet_start - if one_based: - cipher_number += 1 - plaintext_number = 0 if one_based: - plaintext_number = (modular_division_table_one_based[multiplier][(cipher_number - adder + 26) % 26] - 1) % 26 + plaintext_number = (modular_division_table_one_based[multiplier][(cipher_number + 1 - adder + 26) % 26] - 1) % 26 else: - #plaintext_number = (modular_division_table[multiplier][cipher_number] - adder) % 26 plaintext_number = modular_division_table[multiplier][(cipher_number - adder + 26) % 26] return chr(plaintext_number + alphabet_start) else: