fcn playfair(text,keytable){ // text is a-z only keyTable,deadChr:=keytable; text=text.toUpper(); text-=text - keyTable; // remove unencodable characters if(deadChr=="Q") text-=deadChr; else text=text.replace("J","I"); text=text.pump(String,T(Void.Read,1,False), fcn(a,b=""){ if(a==b) a+"X"+b else a+b }); if(text.len().isOdd) text+="Z"; row:='wrap(c){ keyTable.index(c)/5 }; col:='wrap(c){ keyTable.index(c)%5 }; ltrRight:='wrap(c){ keyTable[(keyTable.index(c) + 1)%25] }; ltrBelow:='wrap(c){ keyTable[(keyTable.index(c) + 5)%25] }; ltrAt:='wrap(r,c) { keyTable[r*5 + c] }; text.pump(String, Void.Read, //-->digraph 'wrap(a,b){ if((ra:=row(a))==(rb:=row(b))) return(ltrRight(a) + ltrRight(b)); if((ca:=col(a))==(cb:=col(b))) return(ltrBelow(a) + ltrBelow(b)); return(ltrAt(ra,cb) + ltrAt(rb,ca)); }) .pump(String,Void.Read,"".create.fp(" ")).strip(); // insert blanks }