87 lines
2.1 KiB
Plaintext
87 lines
2.1 KiB
Plaintext
MODULE Caesar EXPORTS Main;
|
|
|
|
IMPORT IO, IntSeq, Text;
|
|
|
|
EXCEPTION BadCharacter;
|
|
(* Used whenever message contains a non-alphabetic character. *)
|
|
|
|
PROCEDURE Encode(READONLY message: TEXT; numbers: IntSeq.T) RAISES { BadCharacter } =
|
|
(*
|
|
Converts upper or lower case letter to 0..25.
|
|
Raises a "BadCharacter" exception for non-alphabetic characters.
|
|
*)
|
|
VAR
|
|
c: CHAR;
|
|
v: INTEGER;
|
|
BEGIN
|
|
FOR i := 0 TO Text.Length(message) - 1 DO
|
|
c := Text.GetChar(message, i);
|
|
CASE c OF
|
|
| 'A'..'Z' => v := ORD(c) - ORD('A');
|
|
| 'a'..'z' => v := ORD(c) - ORD('a');
|
|
ELSE
|
|
RAISE BadCharacter;
|
|
END;
|
|
numbers.addhi(v);
|
|
END;
|
|
END Encode;
|
|
|
|
PROCEDURE Decode(READONLY numbers: IntSeq.T; VAR message: TEXT) =
|
|
(* converts numbers in 0..26 to lower case characters *)
|
|
BEGIN
|
|
FOR i := 0 TO numbers.size() - 1 DO
|
|
message := message & Text.FromChar(VAL(numbers.get(i) + ORD('a'), CHAR));
|
|
END;
|
|
END Decode;
|
|
|
|
PROCEDURE Crypt(numbers: IntSeq.T; key: INTEGER) =
|
|
(*
|
|
In the Caesar cipher, encryption and decryption are really the same;
|
|
one adds the key, the other subtracts it. We can view this as adding a positive
|
|
or nevative integer; the common task is adding an integer. We call this "Crypt".
|
|
*)
|
|
BEGIN
|
|
FOR i := 0 TO numbers.size() - 1 DO
|
|
numbers.put(i, (numbers.get(i) + key) MOD 26);
|
|
END;
|
|
END Crypt;
|
|
|
|
PROCEDURE Encrypt(numbers: IntSeq.T; key := 4) =
|
|
(*
|
|
Encrypts a message of numbers using the designated key.
|
|
The result is also stored in "numbers".
|
|
*)
|
|
BEGIN
|
|
Crypt(numbers, key);
|
|
END Encrypt;
|
|
|
|
PROCEDURE Decrypt(numbers: IntSeq.T; key := 4) =
|
|
(*
|
|
Decrypts a message of numbers using the designated key.
|
|
The result is also stored in "numbers".
|
|
*)
|
|
BEGIN
|
|
Crypt(numbers, -key);
|
|
END Decrypt;
|
|
|
|
VAR
|
|
|
|
message := "";
|
|
buffer := NEW(IntSeq.T).init(22); (* sequence of 22 int's *)
|
|
|
|
BEGIN
|
|
TRY
|
|
Encode("WhenCaesarSetOffToGaul", buffer);
|
|
EXCEPT BadCharacter =>
|
|
(*
|
|
This should never occur.
|
|
Try adding spaces to the above to see what happens.
|
|
*)
|
|
IO.Put("Encountered a bad character in the input; completing partial task\n");
|
|
END;
|
|
Encrypt(buffer);
|
|
Decrypt(buffer);
|
|
Decode(buffer, message);
|
|
IO.Put(message); IO.PutChar('\n');
|
|
END Caesar.
|