Files
dracondi/dracondi.awk
T

97 lines
2.1 KiB
Awk
Raw Normal View History

2025-03-24 10:21:44 +02:00
#!/usr/bin/env awk -f
function prepmsg(s) {
s = tolower(s)
gsub(/[^a-z]/, "", s)
return s
}
function group5(s, l, i) {
l = length(s)
if((l % 5) > 0) {
for(i=l%5;i<5;i++)
s = s CHR[ORD_A + int(rand()*26)]
}
gsub(/.{5}/, "& ", s)
return s
}
function dracondi_key(kp, l, l2, i, r, c, s) {
kp = prepmsg(kp)
l = length(kp)
r = ""
for(i=0;i<l;i++) {
c = substr(kp, i+1, 1)
while(index(r, c) > 0 && length(r) < 26)
c = CHR[ORD_A + ((25 + ORD[c] - ORD_A) % 26)]
r = r c
}
r = r "abcdefghijklmnopqrstuvwxyz"
l2 = length(r)
s = ""
for(i=0;i<l2;i++) {
c = substr(r, i+1, 1)
if(index(s, c) == 0)
s = s c
}
return (substr(s, l+1) substr(s, 0, l))
}
function dracondi_enc(msg, ka1, ka2, offs, l, i, r, c, rc) {
offs = int(rand() * 26)
r = substr(ka1, offs+1, 1)
msg = prepmsg(msg)
l = length(msg)
for(i=0;i<l;i++) {
c = substr(msg, i+1, 1)
rc = substr(ka1, ((index(ka1, c) - 1 + offs) % 26) + 1, 1)
r = r rc
offs = (index(ka2, rc) + i) % 26 # +1 already implied by index
}
return group5(r)
}
function dracondi_dec(msg, ka1, ka2, offs, l, i, r, c, rc) {
msg = prepmsg(msg)
offs = index(ka1, substr(msg,1,1)) - 1
msg = substr(msg, 2)
r = ""
l = length(msg)
for(i=0;i<l;i++) {
c = substr(msg, i+1, 1)
rc = substr(ka1, ((index(ka1, c) + 25 - offs) % 26) + 1, 1)
r = r rc
offs = (index(ka2, c) + i) % 26 # +1 already implied by index
}
return r
}
BEGIN {
srand()
split("", CHR)
split("", ORD)
for(i=0;i<256;i++) {
c = sprintf("%c", i)
CHR[i] = c
ORD[c] = i
}
ORD_A = ORD["a"]
mode = ARGV[ARGC - 3]
ka1 = dracondi_key(ARGV[ARGC - 2])
ka2 = dracondi_key(ARGV[ARGC - 1])
if(mode == "k") {
print "Keyed alphabet 1:", ka1
print "Keyed alphabet 2:", ka2
} else if(mode == "e") {
while(getline msg)
if(length(msg) > 0)
print dracondi_enc(msg, ka1, ka2)
else break
} else if(mode == "d") {
while(getline msg)
if(length(msg) > 0)
print dracondi_dec(msg, ka1, ka2)
else break
} else print "Invalid mode"
}