Task

Implement a   Vigenère cypher,   both encryption and decryption.

The program should handle keys and text of unequal length,
and should capitalize everything and discard non-alphabetic characters. 

(If your program handles non-alphabetic characters in another way,
make a note of it.)



Related tasks

   Caesar cipher
   Rot-13
   Substitution Cipher


PROC Fix(CHAR ARRAY in,fixed)
  INT i
  CHAR c
 
  fixed(0)=0
  FOR i=1 TO in(0)
  DO
    c=in(i)
    IF c>='a AND c<='z THEN
      c==-('a-'A)
    FI
    IF c>='A AND c<='Z THEN
      fixed(0)==+1
      fixed(fixed(0))=c
    FI
  OD
RETURN
 
PROC Process(CHAR ARRAY in,key,out INT dir)
  CHAR ARRAY inFixed(256),keyFixed(256)
  INT keyI,tmp,i
  CHAR c
 
  out(0)=0
  Fix(in,inFixed)
  Fix(key,keyFixed)
  IF inFixed(0)=0 OR keyFixed(0)=0 THEN
    RETURN
  FI
 
  keyI=1
  FOR i=1 TO inFixed(0)
  DO
    c=inFixed(i)
    tmp=c-'A+dir*(keyFixed(keyI)-'A)
    IF tmp<0 THEN
      tmp==+26
    FI
    out(0)==+1
    out(out(0))='A+tmp MOD 26
    keyI==+1
    IF keyI>keyFixed(0) THEN
      keyI=1
    FI
  OD
RETURN
 
PROC Encrypt(CHAR ARRAY in,key,out)
  Process(in,key,out,1)
RETURN
 
PROC Decrypt(CHAR ARRAY in,key,out)
  Process(in,key,out,-1)
RETURN
 
PROC Test(CHAR ARRAY in,key)
  CHAR ARRAY enc(256),dec(256)
 
  PrintE("Original:") PrintE(in)
  Encrypt(in,key,enc)
  PrintF("Encrypted key=%S:%E",key) PrintE(enc)
  Decrypt(enc,key,dec)
  PrintF("Decrypted key=%S:%E",key) PrintE(dec)
  PutE()
RETURN
 
PROC Main()
  Test("Attack at dawn!","LEMONLEMONLE")
 
  Test("Crypto is short for cryptography.","ABCDABCDABCDABCDABCDABCDABCD")
RETURN