Files
dracondi/dracondi.py
T
2025-03-24 10:21:44 +02:00

66 lines
1.9 KiB
Python
Executable File

#!/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()