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


$ include "seed7_05.s7i";
 
const func string: vigenereCipher (in string: source, in var string: keyword) is func
  result
    var string: dest is "";
  local
    var char: ch is ' ';
    var integer: index is 1;
    var integer: shift is 0;
  begin
    keyword := upper(keyword);
    for ch range source do
      if ch in {'A' .. 'Z'} | {'a' .. 'z'} then
        shift := ord(keyword[succ(pred(index) rem length(keyword))]) - ord('A');
        dest &:= chr(ord('A') + (ord(upper(ch)) - ord('A') + shift) rem 26);
        incr(index);
      end if;
    end for;
  end func;
 
const func string: vigenereDecipher (in string: source, in var string: keyword) is func
  result
    var string: dest is "";
  local
    var char: ch is ' ';
    var integer: index is 0;
    var integer: shift is 0;
  begin
    keyword := upper(keyword);
    for ch key index range source do
      if ch in {'A' .. 'Z'} | {'a' .. 'z'} then
        shift := ord(keyword[succ(pred(index) rem length(keyword))]) - ord('A');
        dest &:= chr(ord('A') + (ord(upper(ch)) - ord('A') - shift) mod 26);
      end if;
    end for;
  end func;
 
const proc: main is func
  local
    const string: input is "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!";
    const string: keyword is "VIGENERECIPHER";
    var string: encrypted is "";
    var string: decrypted is "";
  begin
    writeln("Input:     " <& input);
    writeln("key:       " <& keyword);
    encrypted := vigenereCipher(input, keyword);
    writeln("Encrypted: " <& encrypted);
    decrypted := vigenereDecipher(encrypted, keyword);
    writeln("Decrypted: " <& decrypted);
  end func;