-- The Vigenère cipher is a way to encrypt text, where a key is -- repeated for the length of the plaintext and the alphabetical -- position of the keyword letter determines the amount the letter of -- the plaintext is shifted by. For example, for plaintext "FOO" and -- key "BAR", the first letter of the cipher text would be G, the -- result of shifting the letter F (first letter of the plaintext) -- over by 1 (the zero-based alphabetical position of B, first letter -- of the key). -- -- Implement a function to encode a message with a given keyword. The -- message should be converted to upper-case and any non-alphabetical -- characters should be discarded. -- -- Solution -------------------------------------------------------------------- local a_value = 65 function apply_shift(letter, shift) local shifted = (letter - a_value + shift) % 26 return a_value + shifted end function vigenere_encode(plaintext, keyword) local key = {} for i = 1, #keyword do local shift = string.byte(keyword, i) - a_value table.insert(key, shift) end plaintext = string.gsub(string.upper(plaintext), "%A+", "") ciphertext = "" for i = 1, #plaintext do local letter = string.byte(plaintext, i) local shift = key[(i - 1) % #key + 1] local shifted = apply_shift(letter, shift) ciphertext = ciphertext .. string.char(shifted) end return ciphertext end -- Tests ----------------------------------------------------------------------- local luaunit = require("luaunit.luaunit") function test_encoding_of_foo_with_key_BAR() luaunit.assertEquals(vigenere_encode("FOO", "BAR"), "GOF") end function test_encoding_of_the_quick_brown_fox_with_key_JUMPSOVER() local plaintext = "The quick brown fox" local key = "JUMPSOVER" local expected = "CBQFMWXOSAIICXCS" luaunit.assertEquals(vigenere_encode(plaintext, key), expected) end function test_encoding_longer_phrase_with_key_LEAR() local plaintext = "They dined on mince and slices of quince, which they ate with a runcible spoon." local key = "LEAR" local expected = "ELEPOMNVOSNDTRCVLRDJWMCVDSFHFMNTPAHZNLTYPCAKPAIKSERLYGISWISGZSN" luaunit.assertEquals(vigenere_encode(plaintext, key), expected) end os.exit(luaunit.LuaUnit.run())