Playfair cipher: Difference between revisions
Content added Content deleted
m (→{{header|REXX}}: split some compound statements, added/changed whitespace and comments, ordered functions by name, used a template for the output sections.) |
|||
Line 2,088: | Line 2,088: | ||
<br>A fair amount of code was added to massage the decrypted encryption to remove doubled '''X'''es so as to match the original text |
<br>A fair amount of code was added to massage the decrypted encryption to remove doubled '''X'''es so as to match the original text |
||
<br>(this is the ''possible text'' part of the REXX code). |
<br>(this is the ''possible text'' part of the REXX code). |
||
<lang rexx>/*REXX program implements a PLAYFAIR cipher (encryption |
<lang rexx>/*REXX program implements a PLAYFAIR cipher (encryption and decryption). */ |
||
@abc='abcdefghijklmnopqrstuvwxyz'; @abcU=@abc |
@abc= 'abcdefghijklmnopqrstuvwxyz'; @abcU= @abc /*literals for lower and upper ABC's.*/ |
||
parse arg omit key '(' text /*TEXT is the phrase to be used. |
parse arg omit key '(' text /*TEXT is the phrase to be used. */ |
||
⚫ | |||
if key =='' | key ==',' then do; key='Playfair example.'; oldK=key " ◄───using the default."; end |
|||
if |
if key =='' | key ==',' then do; key= 'Playfair example.' |
||
oldKey= key " ◄───using the default." |
|||
end |
|||
if omit=='' | omit==',' then omit= 'J' /*the "omitted" character string. */ |
|||
if |
if text='' then text= 'Hide the gold in the tree stump!!' /*default.*/ |
||
newKey = scrub(key, 1) /*scrub old cipher key ──► newKey */ |
|||
⚫ | |||
newText= scrub(text ) /* " " text ──► newText */ |
|||
if \datatype(omit,'M') then call err 'OMIT letter must be a Latin alphabet letter.' |
|||
if newText=='' then call err 'TEXT is empty or has no letters.' |
|||
⚫ | |||
⚫ | |||
if |
if \datatype(omit, 'M') then call err 'OMIT letter must be a Latin alphabet letter.' |
||
⚫ | |||
if pos(omit,newKey) \==0 then call err 'cipher key' cant |
|||
⚫ | |||
⚫ | |||
if pos(omit, newText)\==0 then call err 'TEXT' @cant |
|||
if |
if pos(omit, newKey) \==0 then call err 'cipher key' @cant |
||
fill=space(translate( |
fill= space( translate(@abcU, , omit), 0) /*elide OMIT characters from alphabet. */ |
||
xx= 'X' /*character used for double characters.*/ |
|||
if omit==xx then xx= 'Q' /* " " " " " */ |
|||
⚫ | |||
if length(newKey)<3 then call err , |
|||
⚫ | |||
'cipher key is too short, must be ≥ 3 unique characters.' |
|||
⚫ | |||
say ' double char: ' xx ; Lxx=translate(xx, @abc, @abcU) |
|||
grid= newKey || fill /*only first 25 characters are used. */ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
say 'new cipher key: ' newKey |
|||
⚫ | |||
say ' omit char: ' omit |
|||
⚫ | |||
say ' double char: ' xx |
|||
⚫ | |||
⚫ | |||
⚫ | |||
padL= 14 + 2 |
|||
if col==5 then do; @.row.6=@.row.1; @.row.0=@.row.5; end |
|||
⚫ | |||
if row==5 then do; @.6.col=@.1.col; @.0.col=@.5.col; end |
|||
#=0 /*number of grid characters used. */ |
|||
do row =1 for 5 /*build array of individual cells. */ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
if col==5 then do; @.row.6= @.row.1; @.row.0= @.row.5; end |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
pad = left('', padL) |
|||
⚫ | |||
⚫ | |||
⚫ | |||
Lxx = translate(xx, @abc, @abcU) /* [↓] lowercase of double character. */ |
|||
⚫ | |||
LxxLxx= Lxx || Lxx /* [↓] doubled version of Lxx. */ |
|||
⚫ | |||
pText= .Playfair(eText ); call show 'plain' , pText |
|||
⚫ | |||
⚫ | |||
⚫ | |||
upper qText /*reinstate the use of upper characters*/ |
|||
⚫ | |||
⚫ | |||
if qtext==newText then say padx 'encryption──► decryption──► encryption worked.' |
if qtext==newText then say padx 'encryption──► decryption──► encryption worked.' |
||
exit /*stick a fork in it, we're done.*/ |
exit /*stick a fork in it, we're all done. */ |
||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
/*──────────────────────────────────one─line subroutines───────────────────────────────*/ |
|||
@@: parse arg Xrow,Xcol; return @.Xrow.Xcol |
@@: parse arg Xrow,Xcol; return @.Xrow.Xcol |
||
err: say; say '***error!***' arg(1); say; exit 13 |
err: say; say '***error!***' arg(1); say; exit 13 |
||
LR: rowL=row(left(__,1)); colL=_; rowR=row(right(__,1)); colR=_; return length(__) |
LR: rowL= row(left(__, 1)); colL= _; rowR= row(right(__,1)); colR= _; return length(__) |
||
row: ?=pos(arg(1),grid); |
row: ?= pos(arg(1), grid); _= (?-1) // 5 + 1; return (4+?) % 5 |
||
show: arg ,y; say; say right(arg(1) 'text: ',padL) digram(y); say pad space(y,0); return |
show: arg ,y; say; say right(arg(1) 'text: ',padL) digram(y); say pad space(y, 0); return |
||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
/*──────────────────────────────────SCRUB subroutine────────────────────*/ |
|||
.Playfair: arg T,encrypt; i= -1; if encrypt==1 then i= 1; $= |
|||
⚫ | |||
do k=1 while i==1; _= substr(T, k, 1); if _==' ' then leave |
|||
if |
if _==substr(T, k+1, 1) then T= left(T, k) || Lxx || substr(T, k + 1) |
||
end /*k*/ |
|||
upper T |
|||
do j=1 by 2 to length(T); __= strip( substr(T, j, 2) ) |
|||
⚫ | |||
if LR()==1 then __= __ || xx; call LR /*append X or Q char, rule 1*/ |
|||
/*──────────────────────────────────DIGRAM subroutine───────────────────*/ |
|||
select |
|||
when rowL==rowR then __= @@(rowL, colL+i)@@(rowR, colR+i) /*rule 2*/ |
|||
when colL==colR then __= @@(rowL+i, colL )@@(rowR+i, colR) /*rule 3*/ |
|||
⚫ | |||
⚫ | |||
end /*select*/ |
|||
/*──────────────────────────────────.PLAYFAIR subroutine────────────────*/ |
|||
$= $ || __ |
|||
end /*j*/ |
|||
⚫ | |||
if _==substr(T,k+1 ,1) then T=left(T,k) || Lxx || substr(T,k+1) |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
⚫ | |||
digram: procedure; parse arg x; $=; do j=1 by 2 to length(x) |
|||
upper T |
|||
$= $ || substr(x, j, 2)' ' |
|||
end /*j*/ |
|||
⚫ | |||
select |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
⚫ | |||
⚫ | |||
when colL==colR then __=@@(rowL+i,colL )@@(rowR+i,colR) /*rule 3*/ |
|||
$=; do j=1 for length(xxx); _= substr(xxx, j, 1) |
|||
if unique==1 then if pos(_, $)\==0 then iterate /*is unique?*/ |
|||
⚫ | |||
if datatype(_, 'M') then $= $ || _ /*only use Latin letters. */ |
|||
$=$ || __ |
|||
end /*j*/ |
end /*j*/ |
||
return $</lang> |
return $</lang> |
||
Some older REXXes don't have a '''changestr''' bif, so one is included here ──► [[CHANGESTR.REX]]. |
Some older REXXes don't have a '''changestr''' bif, so one is included here ──► [[CHANGESTR.REX]]. |
||
<br><br> |
<br><br> |
||
{{out|output|text= when using the default inputs:}} |
|||
<pre> |
<pre> |
||
old cipher key: Playfair example. ◄───using the default. |
old cipher key: Playfair example. ◄───using the default. |
||
Line 2,192: | Line 2,201: | ||
════════════════Playfair encryption──► decryption──► encryption worked. |
════════════════Playfair encryption──► decryption──► encryption worked. |
||
</pre> |
</pre> |
||
{{out|output|text= when using the input of: <tt> x stuvw (myteest </tt>}} |
|||
<pre> |
<pre> |
||
old cipher key: stuvw |
old cipher key: stuvw |