#!/usr/bin/env python3 # DRACONDI: Dual-key Rotating Alphabet CONDI import sys, re from collections import OrderedDict from random import randint, choice from string import ascii_lowercase def prepmsg(s:str): return re.sub(r'[^a-z]', '', s.lower()) def dracondi_key(keyphrase:str): prekey = '' oa = ord('a') for c in prepmsg(keyphrase): while prekey.find(c) != -1 and len(prekey) < 26: c = chr(oa + ((25 + ord(c) - oa) % 26)) prekey += c offs = len(prekey) % 26 alpha = prekey + ''.join(ascii_lowercase) unshifted = ''.join(list(OrderedDict.fromkeys(alpha).keys())) return (unshifted + unshifted)[offs:offs+26] def dracondi_enc(msg:str, ka1:str, ka2:str): offs = randint(0, 25) res = ka1[offs] for i,c in enumerate(prepmsg(msg)): rc = ka1[(ka1.index(c) + offs) % 26] res += rc offs = (ka2.index(rc) + i + 1) % 26 l = len(res) % 5 if l > 0: res += ''.join([choice(ascii_lowercase) for i in range(0, 5 - l)]) return ' '.join([res[i:i+5] for i in range(0, len(res), 5)]) def dracondi_dec(msg:str, ka1:str, ka2:str): res = '' msg = prepmsg(msg) offs = ka1.index(msg[0]) for i,c in enumerate(msg[1:]): res += ka1[(26 + ka1.index(c) - offs) % 26] offs = (ka2.index(c) + i + 1) % 26 return res # entrypoint parameters: [mode] [key1] [key2] # modes: e - encrypt, d - decrypt, k - print out keyed alphabets def main(): mode = sys.argv[1].lower() kp1 = sys.argv[2] kp2 = sys.argv[3] ka1 = dracondi_key(kp1) ka2 = dracondi_key(kp2) if mode.startswith('e'): msg = sys.stdin.read() print(dracondi_enc(msg, ka1, ka2)) elif mode.startswith('k'): print('Keyed alphabet 1:', ka1) print('Keyed alphabet 2:', ka2) else: msg = sys.stdin.read() print(dracondi_dec(msg, ka1, ka2)) if __name__ == '__main__': main()