X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=cipher.py;h=86125b38e805654f0957ec5e4fd27d7e285c5177;hb=5334c6e49cc35db0df35322a77ba0efe94a4abdd;hp=4c3f14b00ab3c8ce8c0f37aae144d9470bdb8d35;hpb=2199c12469620a8de4274518e5d0090142468d5b;p=cipher-tools.git diff --git a/cipher.py b/cipher.py index 4c3f14b..86125b3 100644 --- a/cipher.py +++ b/cipher.py @@ -13,6 +13,7 @@ import pprint ## Utility functions cat = ''.join wcat = ' '.join +lcat = '\n'.join def pos(letter): if letter in string.ascii_lowercase: @@ -381,7 +382,7 @@ def vigenere_encipher(message, keyword): >>> vigenere_encipher('hello', 'abc') 'hfnlp' """ - shifts = [ord(l) - ord('a') for l in sanitise(keyword)] + shifts = [pos(l) for l in sanitise(keyword)] pairs = zip(message, cycle(shifts)) return cat([caesar_encipher_letter(l, k) for l, k in pairs]) @@ -391,12 +392,25 @@ def vigenere_decipher(message, keyword): >>> vigenere_decipher('hfnlp', 'abc') 'hello' """ - shifts = [ord(l) - ord('a') for l in sanitise(keyword)] + shifts = [pos(l) for l in sanitise(keyword)] pairs = zip(message, cycle(shifts)) return cat([caesar_decipher_letter(l, k) for l, k in pairs]) -beaufort_encipher=vigenere_decipher -beaufort_decipher=vigenere_encipher + +def beaufort_encipher(message, keyword): + """Beaufort encipher + + >>> beaufort_encipher('inhisjournaldatedtheidesofoctober', 'arcanaimperii') + 'sevsvrusyrrxfayyxuteemazudmpjmmwr' + """ + shifts = [pos(l) for l in sanitise(keyword)] + pairs = zip(message, cycle(shifts)) + return cat([unpos(k - pos(l)) for l, k in pairs]) + +beaufort_decipher = beaufort_encipher + +beaufort_variant_encipher=vigenere_decipher +beaufort_variant_decipher=vigenere_encipher def polybius_grid(keyword, column_order, row_order, letters_to_merge=None, @@ -890,12 +904,12 @@ def hill_encipher(matrix, message_letters, fillvalue='a'): padding = fillvalue[0] * (n - len(sanitised_message) % n) else: padding = '' - message = [ord(c) - ord('a') for c in sanitised_message + padding] + message = [pos(c) for c in sanitised_message + padding] message_chunks = [message[i:i+n] for i in range(0, len(message), n)] # message_chunks = chunks(message, len(matrix), fillvalue=None) enciphered_chunks = [((matrix * np.matrix(c).T).T).tolist()[0] for c in message_chunks] - return cat([chr(int(round(l)) % 26 + ord('a')) + return cat([unpos(round(l)) for l in sum(enciphered_chunks, [])]) def hill_decipher(matrix, message, fillvalue='a'): @@ -1157,7 +1171,7 @@ class PocketEnigma(object): self.validate_wheel_spec(wheel) self.make_wheel_map(wheel) if position in string.ascii_lowercase: - self.position = ord(position) - ord('a') + self.position = pos(position) else: self.position = position @@ -1171,8 +1185,8 @@ class PocketEnigma(object): self.validate_wheel_spec(wheel_spec) self.wheel_map = [0] * 26 for p in wheel_spec: - self.wheel_map[ord(p[0]) - ord('a')] = ord(p[1]) - ord('a') - self.wheel_map[ord(p[1]) - ord('a')] = ord(p[0]) - ord('a') + self.wheel_map[pos(p[0])] = pos(p[1]) + self.wheel_map[pos(p[1])] = pos(p[0]) return self.wheel_map def validate_wheel_spec(self, wheel_spec): @@ -1227,10 +1241,9 @@ class PocketEnigma(object): '' """ if letter in string.ascii_lowercase: - return chr( - (self.wheel_map[(ord(letter) - ord('a') - self.position) % 26] + - self.position) % 26 + - ord('a')) + return unpos( + (self.wheel_map[(pos(letter) - self.position) % 26] + + self.position)) else: return '' @@ -1278,7 +1291,7 @@ class PocketEnigma(object): >>> pe.set_position('z') 25 """ - self.position = ord(position) - ord('a') + self.position = pos(position) return self.position