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


procedure main()
   ptext := "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
   write("Key        = ",ekey := "VIGENERECIPHER")
   write("Plain Text = ",ptext)
   write("Normalized = ",GFormat(ptext := NormalizeText(ptext)))
   write("Enciphered = ",GFormat(ctext := Vignere("e",ekey,ptext)))
   write("Deciphered = ",GFormat(ptext := Vignere("d",ekey,ctext)))
end
 
procedure Vignere(mode,ekey,ptext,alpha)   #: Vignere cipher
   /alpha := &ucase                                              # default 
   if *alpha ~= *cset(alpha) then runerr(205,alpha)              # no dups
   alpha ||:= alpha                                              # unobstructed
 
   every ctext:="" & p:=ptext[i := 1 to *ptext] & k:=ekey[(i-1)%*ekey+1] do 
      case mode of {
         "e"|"encrypt": 
            ctext||:=map(p,alpha[1+:*alpha/2],alpha[find(k,alpha)+:(*alpha/2)])
         "d"|"decrypt": 
            ctext||:=map(p,alpha[find(k,alpha)+:(*alpha/2)],alpha[1+:*alpha/2])
         default: runerr(205,mode)
      }
return ctext
end