Playfair cipher: Difference between revisions

Content deleted Content added
Line 1,478: Line 1,478:


=={{header|zkl}}==
=={{header|zkl}}==
<lang zkl>fcn genKeyTable(key,deadChr){ // deadChr=="Q" or "J"
Punting Q out of the alphabet.
deadChr=deadChr.toUpper();
<lang zkl>fcn genKeyTable(key){
key=(key - " qQ").toUpper().unique();
key=key.toUpper().unique() - " " - deadChr;
key + (["A".."Z"].aggregate(String).walk() - "Q" - key);
return(key + (["A".."Z"].pump(String) - deadChr - key), deadChr);
}</lang>
}</lang>
<lang zkl>fcn playfair(text,keyTable){ // text is a-z only
<lang zkl>fcn playfair(text,keytable){ // text is a-z only
keyTable,deadChr:=keytable;
text=text.toUpper();
text=text.toUpper();
text-=text - keyTable; // remove unencodable characters
text-=text - keyTable; // remove unencodable characters
if(text.len().isOdd) text+="Z";
if(deadChr=="Q") text-=deadChr; else text=text.replace("J","I");

row:='wrap(c){ keyTable.index(c)/5 };
row:='wrap(c){ keyTable.index(c)/5 };
col:='wrap(c){ keyTable.index(c)%5 };
col:='wrap(c){ keyTable.index(c)%5 };
ltrRight:='wrap(c){ keyTable[(keyTable.index(c)+1)%25] };
ltrRight:='wrap(c){ keyTable[(keyTable.index(c) + 1)%25] };
ltrBelow:='wrap(c){ keyTable[(keyTable.index(c)+5)%25] };
ltrBelow:='wrap(c){ keyTable[(keyTable.index(c) + 5)%25] };
ltrAt:='wrap(r,c){ keyTable[r*5+c] };
ltrAt:='wrap(r,c) { keyTable[r*5 + c] };

(text.toUpper()-"Q").pump(String,Void.Read, //-->digraph
'wrap(a,b){
sink:=Sink(String);
foreach a in (text){
if(a==b) b="X";
b:=__aWalker._next() and __aWalker.value or "X";
if((ra:=row(a))==(rb:=row(b))) return(ltrRight(a)+ltrRight(b));
if(a==b){
if((ca:=col(a))==(cb:=col(b))) return(ltrBelow(a)+ltrBelow(b));
if(b=="X"){ // "XX" is pathological
return(ltrAt(ra,cb)+ltrAt(rb,ca));
if(not __aWalker.atEnd) __aWalker.push(b);
});
b="Z";
}
else { __aWalker.push(b); b="X"; }
}
sink.write(
if((ra:=row(a))==(rb:=row(b))) ltrRight(a) + ltrRight(b);
else if((ca:=col(a))==(cb:=col(b))) ltrBelow(a) + ltrBelow(b);
else ltrAt(ra,cb) + ltrAt(rb,ca);
);
}
sink.close()
.pump(String,Void.Read,"".create.fp(" ")).strip(); // insert blanks
}</lang>
}</lang>
<lang zkl>fcn decodePF(text,keyTable){
<lang zkl>fcn decodePF(text,keyTable){
keyTable,_=keyTable;
text-=" ";
row:='wrap(c){ keyTable.index(c)/5 };
row:='wrap(c){ keyTable.index(c)/5 };
col:='wrap(c){ keyTable.index(c)%5 };
col:='wrap(c){ keyTable.index(c)%5 };
ltrLeft:='wrap(c){ keyTable[(keyTable.index(c)-1)%25] };
ltrLeft:='wrap(c){ keyTable[(keyTable.index(c) - 1)%25] };
ltrUp:='wrap(c){ n:=keyTable.index(c)-5; if(n<0)n+=25; keyTable[n%25] };
ltrUp:='wrap(c){ n:=keyTable.index(c) - 5; if(n<0)n+=25; keyTable[n%25] };
ltrAt:='wrap(r,c){ keyTable[r*5+c] };
ltrAt:='wrap(r,c){ keyTable[r*5 + c] };
text.pump(String,Void.Read, //-->digraph
text.pump(String,Void.Read, //-->digraph
'wrap(a,b){
'wrap(a,b){
if((ra:=row(a))==(rb:=row(b))) return(ltrLeft(a)+ltrLeft(b));
if((ra:=row(a))==(rb:=row(b))) return(ltrLeft(a) + ltrLeft(b));
if((ca:=col(a))==(cb:=col(b))) return(ltrUp(a)+ltrUp(b));
if((ca:=col(a))==(cb:=col(b))) return(ltrUp(a) + ltrUp(b));
return(ltrAt(ra,cb)+ltrAt(rb,ca));
return(ltrAt(ra,cb) + ltrAt(rb,ca));
});
})
.pump(String,Void.Read,"".create.fp(" ")).strip(); // insert blanks
}</lang>
}
</lang>
<lang zkl>msg:="Hide the gold in the tree stump!!!";
<lang zkl>msg:="Hide the gold in the tree stump!!!";
keyTable:=genKeyTable("playfair example");
keyTable:=genKeyTable("playfair example");
msg.println();
msg.println();
e:=playfair(msg,keyTable); e.println();
e:=playfair(msg,keyTable); e.println();
decodePF(e,keyTable).println();</lang>
decodePF(e,keyTable).println();
decodePF(playfair("X",keyTable).println(),keyTable).println();
decodePF(playfair("XX",keyTable).println(),keyTable).println();</lang>
{{out}}
{{out}}
<pre>
<pre>
Hide the gold in the tree stump!!!
Hide the gold in the tree stump!!!
BM OD ZB XD NA BE KU DM UI XM MO UV IF
BMNDZBXDKYBEJVDMUIXMJZZRFT
HI DE TH EG OL DI NT HE TR EX ES TU MP
HIDETHEGOLDINTHETREXSTUMPZ
MW
XZ
MW MW
XZ XZ
</pre>
</pre>