Playfair cipher: Difference between revisions
Content added Content deleted
(→{{header|REXX}}: fixed two unset variables. -- ~~~~) |
(→{{header|REXX}}: added more diagnostic output, added "possible text" (which deletes the character used for double characters in the original text), used preferred spelling of cipher. -- ~~~~) |
||
Line 361: | Line 361: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
Quite a bit of the REXX code deals with error checking, accepting arguments, and displaying the options used. |
Quite a bit of the REXX code deals with error checking, accepting arguments, and displaying the options used. |
||
<lang rexx>/*REXX program implements a PLAYFAIR |
<lang rexx>/*REXX program implements a PLAYFAIR cipher (encryption & decryption).*/ |
||
arg oldK |
parse arg key . 1 oldK omit _ . '(' text /*TEXT is the phrase to be used*/ |
||
if |
if key =='' | key ==',' then do; key='Playfair example.'; oldK=key " ◄───the default."; end |
||
if |
if omit=='' | omit==',' then omit='J' /*the "omitted" character. */ |
||
if |
if text='' then text='Hide the gold in the tree stump!!' /*default.*/ |
||
key =scrub(key) /*use only Latin alphabet letters*/ |
|||
⚫ | |||
newText=scrub(text) /* " " " " " */ |
|||
newX=scrub(oldX) /* " " " " " */ |
|||
if _\=='' then call err 'too many arguments specified.' |
if _\=='' then call err 'too many arguments specified.' |
||
if |
if newText=='' then call err 'TEXT is empty or has no letters' |
||
if length( |
if length(omit)\==1 then call err 'OMIT letter must be only one letter' |
||
if \datatype( |
if \datatype(omit,'M') then call err 'OMIT letter must be a Latin alphabet letter.' |
||
if pos( |
if pos(omit,text)\==0 then call err 'TEXT can''t contain the "OMIT" character: ' omit |
||
⚫ | |||
fill=space(translate('ABCDEFGHIJKLMNOPQRSTUVWXYZ',, |
fill=space(translate('ABCDEFGHIJKLMNOPQRSTUVWXYZ',,omit),0) /*elide omit*/ |
||
⚫ | |||
newKey= /* [↓] remove any duplicate chars*/ |
|||
do j=1 for length(key); _=substr(key,j,1) |
|||
if pos(_,newKey)==0 then newKey=newKey || _ |
|||
end /*j*/ |
end /*j*/ |
||
xx='X'; if omit==xx then xx='Q' /*char used for double characters*/ |
|||
if length( |
if length(newKey)<3 then call err 'cipher key is too short, must be > 2 unique characters.' |
||
⚫ | |||
fill=space(translate(fill,,newKey),0) /*remove any cipher characters. */ |
|||
grid=left(newKey || fill,26) /*use only the first 25 chars. */ |
|||
⚫ | |||
say ' old |
say ' old cipher: ' strip(oldK) |
||
say ' new |
say ' new cipher: ' newKey |
||
say ' |
say ' omit char : ' omit |
||
say 'double char : ' xx |
|||
⚫ | |||
⚫ | |||
say 'digram text ↔: ' digram(newText) |
|||
#=0 |
#=0 |
||
do row =1 for 5 /*build grid (individual cells).*/ |
do row =1 for 5 /*build grid (individual cells).*/ |
||
Line 395: | Line 399: | ||
end /*row*/ |
end /*row*/ |
||
say |
say |
||
cText=.playfair( |
cText=.playfair(newText, 1); say ' cipher text: ' digram(cText) |
||
pText=.playfair(cText |
pText=.playfair(cText ); say ' plain text: ' digram(pText) |
||
⚫ | |||
if length(qText)\==length(pText) then say 'possible text: ' digram(qText) |
|||
exit /*stick a fork in it, we're done.*/ |
exit /*stick a fork in it, we're done.*/ |
||
/*──────────────────────────────────one-line subroutines────────────────*/ |
/*──────────────────────────────────one-line subroutines────────────────*/ |
||
Line 415: | Line 421: | ||
return strip($) |
return strip($) |
||
/*──────────────────────────────────.PLAYFAIR subroutine────────────────*/ |
/*──────────────────────────────────.PLAYFAIR subroutine────────────────*/ |
||
.playfair: parse arg T,encrypt; i=-1; if encrypt then i=1; $= |
.playfair: parse arg T,encrypt; i=-1; if encrypt==1 then i=1; $= |
||
do k=1 while |
do k=1 while i==1; _=substr(T,k,1); if _='' then leave |
||
if _==substr(T,k+1,1) then T=left(T,k) || |
if _==substr(T,k+1,1) then T=left(T,k) || xx || substr(T,k+1) |
||
end /*k*/ |
end /*k*/ |
||
do j=1 by 2 to length(T); __=strip(substr(T,j,2)); call LR |
do j=1 by 2 to length(T); __=strip(substr(T,j,2)); call LR |
||
if length(__)==1 then __=__ || |
if length(__)==1 then __=__ || xx; call LR /*append X|Q char, rule 1*/ |
||
select |
select |
||
when rowL==rowR then __=@@(rowL, colL+i)@@(rowR, colR+i) /*rule 2*/ |
when rowL==rowR then __=@@(rowL, colL+i)@@(rowR, colR+i) /*rule 2*/ |
||
Line 431: | Line 437: | ||
'''output''' when using the default inputs: |
'''output''' when using the default inputs: |
||
<pre> |
<pre> |
||
old |
old cipher: Playfair example. ◄───the default. |
||
new |
new cipher: PLAYFIREXM |
||
omit char : J |
|||
old phrase= Hide the gold in the tree stump!! |
|||
double char : X |
|||
⚫ | |||
old text : Hide the gold in the tree stump!! |
|||
⚫ | |||
digram text ↔: HI DE TH EG OL DI NT HE TR EE ST UM P |
|||
cipher text: BM OD ZB XD NA BE KU DM UI XM MO UV IF |
|||
plain text |
plain text: HI DE TH EG OL DI NT HE TR EX ES TU MP |
||
possible text: HI DE TH EG OL DI NT HE TR EE ST UM P |
|||
</pre> |
</pre> |
||
After the usual replacements for $, @, #, and x= I ran the program on ooRexx with the following correct results: |
After the usual replacements for $, @, #, and x= I ran the program on ooRexx with the following correct results: |