RosettaCodeData/Task/Bifid-cipher/XPL0/bifid-cipher.xpl0
2024-10-16 18:07:41 -07:00

101 lines
2.8 KiB
Text

string 0; \use zero-terminated strings
def MaxLen = 100; \more than length of longest message
func StrLen(A); \Return number of characters in an ASCIIZ string
char A;
int I;
for I:= 0 to MaxLen do
if A(I) = 0 then return I;
proc StrUpper(S); \In string S, convert lowercase characters to uppercase
char S;
int I;
for I:= 0 to StrLen(S)-1 do
if S(I)>=^a & S(I)<=^z then S(I):= S(I) & $DF;
proc StrReplace(S, C1, C2); \In string S, convert character C1 to C2
char S, C1, C2;
int I;
for I:= 0 to StrLen(S)-1 do
if S(I) = C1 then S(I):= C2;
func IndexOf(S, C); \Return offset of character C in string S
char S, C;
int I;
[for I:= 0 to StrLen(S)-1 do
if S(I) = C then return I;
return -1;
];
char Encrypted(MaxLen), Decrypted(MaxLen);
proc Encrypt(Polybius, Message); \Copy encrypted Message into Encrypted
char Polybius, Message;
char Rows(MaxLen*2), Cols(MaxLen);
int C, IX, I, J, Len;
[Len:= StrLen(Message);
for I:= 0 to Len do \copy Message into Encrypted
Encrypted(I):= Message(I);
StrUpper(Encrypted);
StrReplace(Encrypted, ^J, ^I);
I:= 0; J:= 0;
loop [C:= Encrypted(I);
I:= I+1;
if C = 0 then quit;
IX:= IndexOf(Polybius, C);
if IX >= 0 then \ignores spaces, etc.
[Rows(J):= IX/5;
Cols(J):= rem(0);
J:= J+1;
];
];
Len:= J; \length of encrypted message
for I:= 0 to Len-1 do \append Cols onto end of Rows
Rows(I+Len):= Cols(I);
for I:= 0 to Len-1 do
[IX:= Rows(I*2)*5 + Rows(I*2+1);
Encrypted(I):= Polybius(IX);
];
Encrypted(I):= 0; \terminate string
];
proc Decrypt(Polybius, Message); \Copy decrypted Message into Decrypted
char Polybius, Message;
char Rows(MaxLen*2), Cols(MaxLen);
int C, IX, I, J, Len;
[I:= 0; J:= 0;
loop [C:= Message(I);
if C = 0 then quit;
I:= I+1;
IX:= IndexOf(Polybius, C);
Rows(J):= IX/5;
Rows(J+1):= rem(0);
J:= J+2;
];
Len:= I;
Cols:= Rows + Len;
for I:= 0 to Len-1 do
[IX:= Rows(I)*5 + Cols(I);
Decrypted(I):= Polybius(IX);
];
Decrypted(I):= 0;
];
int Polys, Msgs, I;
[Polys:= ["ABCDEFGHIKLMNOPQRSTUVWXYZ",
"BGWKZQPNDSIOAXEFCLUMTHYVR",
"BGWKZQPNDSIOAXEFCLUMTHYVR",
"PLAYFIREXMBCDGHKNOQSTUVWZ"];
Msgs:= ["ATTACKATDAWN",
"FLEEATONCE",
"ATTACKATDAWN",
"The invasion will start on the first of January"];
for I:= 0 to 4-1 do
[Encrypt(Polys(I), Msgs(I));
Decrypt(Polys(I), Encrypted);
Text(0, "Message : "); Text(0, Msgs(I)); CrLf(0);
Text(0, "Encrypted : "); Text(0, Encrypted); CrLf(0);
Text(0, "Decrypted : "); Text(0, Decrypted); CrLf(0);
if I < 4-1 then CrLf(0);
];
]