import Char (ord, chr, toUpper, isAlpha)

tableStart = ord 'A'

toP x = ord (toUpper x) - tableStart
fromP x = chr (x + tableStart)

general_table op x y
	| isAlpha x = fromP $ ((toP x) `op` (toP y)) `mod` 26
	| otherwise = x

encode_table = general_table (+)
decode_table = general_table (-)

code_phrase [] ys = ys
code_phrase (x:xs) (y:ys)
	| isAlpha x = y : (code_phrase xs ys)
	| otherwise = ' ' : (code_phrase xs (y:ys))

vigenere table input codeword =
	zipWith table input (code_phrase input (cycle codeword))

vigenere_encode = vigenere encode_table
vigenere_decode = vigenere decode_table


