
program r (infile, outfile, input, output);

{******************************************************************************}
	{Program for encryption and decryption using the rotation method.
	-Chris Boshuizen

	This rotation program is a shifts letters by some algorithm, f(n). 

	While this program can encrypt/decrypt with any algorithm, it is only
	required to deal with n to the power, p, multiplied by some number, r.

    	f(n) = r.n^p

	ie: shift 1st letter by 1, second by 2, ..shift n th letter n places.
	or: shift 1st letter by 1, second by 4, ..shift n th letter n^2 places.
  	  : etc...

	an example key 	:	abcdefghijklmnopqrstuvwxyz
	f(n) = n	:	bdfhjlnprtvxzbdfhjlnprtvxz
	f(n) = n^2	:	bfltdpdtlfbzzbfltdpdtlfbzz
	f(n) = 2n 	:	cfiloruxadgjmpsvybehknqtwz




	Thanks to Stuart Prescott for the procedures isletter.i and lowercase.i,
	and for the help including them. }

{******************************************************************************}


const 
     	cap= 26; 		{this is the length of the cypher-text (ct) 
				alphabet.  Can be 1<=cap<=26, but a 
				reasonable lower limit is 10<=cap<=26}

var	 
	counter,		{position of each character being read}
 	n,			{the n th Character being shifted}
	cti,			{ascii value of ct}
	r			{the rotation number}
		: integer;  	
	
	pt, 			{plaintext}
	ct			{cyphertext}
		: char;  
	 
    	infile,			{input file}
	outfile 		{output file}
		:text;
  
{******************************************************************************}

{*** requires    isletter.i
     and         lowercase.i}
 
#include "isletter.i"  		{restricts read to lowercase 'a' to 'z'}
#include "lowercase.i" 		{changes uppercase to lowercase}

{******************************************************************************}

begin  {main}
    writeln ('Enter rotation number');
    read (r);
    reset (infile);   
    rewrite (outfile);
    counter:=1; {start at the beginning of the input file}
	while not eof(infile) do begin
	    if eoln(infile) then begin
	        readln(infile);
		writeln(outfile);
	    end
	    else begin
		read(infile, pt); 
		if isletter(pt) then begin
		    n := ((counter mod cap) + cap) mod cap ; 
	      	    pt:= lowercase(pt);
		    cti:= (((ord(pt) - ord('a')+1) + (((n*r)))) mod 26 +26)mod 26 + ord('a')-1;
		    if cti > (ord('z')) then cti:= cti - 26;	{for r>0, if shifted past z,
								 puts ct back to a}
		    if cti < (ord ('a')) then cti:= cti+ 26;	{for r<0, if shifted below a,
								 puts ct back to z} 
	            counter:=counter+1;		
		end
		else begin
		    cti:=ord(pt); 	{don't change the pt if not lowercase a - z}
		end;
	    ct:=chr(cti);		{changes the value of cti into a char ct   }
	    write(outfile, ct);		{and writes ct to the out file		   }
	end;{if eoln}
    end; {while not eof(infile)}
end.  {main}

