%endoflist

{***************************************}
{**                                   **}
{** Encryption & Decryption Routines  **}
{** PR April 84                       **}
{**                                   **}
{** Utilises the fact that XORing a   **}
{** character twice with the same no. **}
{** gives you the original character. **}
{**                                   **}
{***************************************}

%constinteger Key Length = 20                        {** Length of Key Array **}

                                        {** KEY - an array of random numbers **}
                                        {**       used for XOR encrypting    **}

%constbytearray Key (1:Key Length) = 31, 7, 12, 27, 118, 27, 3, 7, 10, 27,
                                     3, 27, 70, 10, 4, 6, 13, 27, 4, 12

%integer Key No = 1                   {** The value of KEYNO gives the start **}
                                      {** element of KEY. The user can give  **}
                                      {** a different value if necessary.    **}

{** ---===<<< Encryption Routines >>>===--- **}

%routine Code Symbol (%integer i)
{**
{** Analogue to PRINT SYMBOL - prints the encrypted version of symbol I by
{** XORing it with the current element of KEY.
{** 
   Print Symbol (i !! Key (Key No))
   Key No = Rem (Key No, Key Length) + 1  {** Advance to next element of KEY **}
%end


%routine Code NL
{** 
{** Analogue to NEWLINE - plants an encrypted Newline character
{** 
   Code Symbol (NL)
%end


%routine Code String (%string (255) S)
{** 
{** Encrypts the string S
{** 
%integer i
   Code Symbol (CharNo (S,i)) %for i = 1,1,Length(S)
%end


%routine Code Write (%integer i)
{** 
{** Partial analogue to WRITE - Encrypts a positive integer I by planting the 
{** encrypted version of each digit. Negative numbers become zero
{**
%short p10
   Code Symbol ('0') %and %return %if i <=0
   %if i < 10 %then p10 = 1 %else p10 = 10^^Int Pt (Log Ten (i))
   %cycle
      Code Symbol (i//p10 + '0')
      i = Rem (i,p10)
      p10 = p10//10
   %repeatuntil p10 = 0
%end


{** ---===<<< Decryption Routines >>>===--- **}

%integerfn Decode Symbol
{** 
{** Analogue to READ SYMBOL - decrypts one symbol and returns it. It is a
{** function rather than a routine because I found this convenient
{** 
%integer s
   Read Symbol (s)
   s = s !! Key (Key No)
   Key No = Rem (Key No, Key Length) + 1       {** On to next element of KEY **}
   %result = s
%end


%integerfn Decode Next
{** 
{** Analogue to NEXT SYMBOL - returns encrypted symbol without advancing to the 
{** next element of KEY.
{** 
   %result = Next Symbol !! Key (Key No)
%end


%routine Decode Skip
{** 
{** Analogue to SKIP SYMBOL - throws away the next symbol, and advances to the
{** next element of KEY.
{** 
%integer Dummy
   Dummy = Decode Symbol
%end


%string (255) %fn Decode String
{** 
{** Decrypts the next string ending in NL or of max length 254 (255 => error)
{** 
%integer s
%bytename L
%string (255) T
   L == Length (T)
   T = ""
   T = T.ToString(Decode Symbol) %while Decode Next # NL %and L < 255
   %result = T
%end


%integerfn Decode Integer
{** 
{** Returns the next positive integer, ie: a sequence of decrypted digits.
{** 
%integer N = 0
   %result = -1 %if %not '0' <= Decode Next <= '9'
   N = N * 10 + Decode Symbol - '0' %while '0' <= Decode Next <= '9'
   %result = N
%end

%list
