# Vigenère cipher encryption in Scala

I've worked out a functioning Vigenère encryption in Scala, and while it doesn't seem like my code is too hideous, I'm sure I could make it more functional and Scala-esque. Primarily, it seems like:

1. I've made the full key with a for-expression / zipWithIndex, I'm wondering if this is the best way to do this though. Would it be better to do this inside the encipher() function? Using an anonymous function? The way I have it now works, but I'm curious if there's a way to do so that'd be more in line with Scala best practices.
2. The actual encryption portion, specifically the output for case (c, i), is sort of messy/convoluted, and it seems like there might be a better way to do it.

Of course, I'll be grateful for any feedback. Definitely still getting my feet wet with Scala, and any help getting into a more functional state of mind would be appreciated.

object Vigenere {

// alphabet for use throughout object
private val alphabet = ('A' to 'Z').toList
//empty array to be filled with fillTabula() function
private var tabulaRecta = Array.ofDim[Char](26, 26)

/* fills the tabula recta array
** creates 26 rows of alphabets, each alphabet shifted
** left by one letter each iteration */
def fillTabula() = {
for (row <- 0 to 25) {
for (col <- 0 to 25) {
tabulaRecta(row)(col) = alphabet((row + col) % 26)
}
}
}

/* create the full key by repeating the key until its as long
** as the plaintext. */
def makeFullkey(key: String, text:String): String = {
val fkey = for (c <- text.zipWithIndex) yield c match {
case (c, i) => key(i % key.length)
}
return fkey.mkString
}

def encipher(key: String, text:String): String = {
// fill the tabula recta
fillTabula()
val fkey = makeFullkey(key, text)

/* to encipher, zip the plaintext to return each letter with
** its index. if it's a space, just add space to ciphertext.
** if it's not a space, find the corresponding row in the
** tabula recta, then go to the appropriate column to
** return the ciphertext character.
** the second case here is a mess, there's got to be a nicer way. */

val ciphertext = for (c <- text.zipWithIndex) yield c match {
case (' ', _) => ' '
case (c, i)   => tabulaRecta(alphabet.indexOf(fkey(i)))(alphabet.indexOf(c))
}
return ciphertext.mkString
}

def main(args: Array[String]) {
val Array(text, key) = args

println("Plaintext: " + text)
println("Key: " + key)
println("Ciphertext: " + encipher(key.toUpperCase, text.toUpperCase))

}
}


Edit: I realized that I could make the fullkey using zipWithIndex as well, and also found a better place to use toUpperCase. I've changed the code and updated my question accordingly.

I'm not a scala/fp expert but here is my 2 cents.

Your code reads very much like you have read the definition on wikipedia and translated it into scala. As the wikipedia definition is written as a human implemented algorithm you end up with a very procedural approach.

A few specific things:

• tabulaRecta - this is constant, making it a var is a massive code smell
• makeFullkey - you use zipWithIndex but don't use c, just use index
• why can't tabulaRecta be a function?
• why create a fullKey - can't you compute the key char as a function?
• Hmm, I honestly have no idea how I'd go about making tabulaRecta into a function at this point, I'd certainly prefer it being a val too. I'm sure you're right about the fullKey thing too. I used zipWithIndex on the fullKey so as to avoid using an accumulating counter variable, but I'm sure there's a better way to do that too. Thanks for giving me some stuff to think about! – djc Jul 29 '15 at 16:01
• Let me know if want more help, I can post some actual code as well. I thought it best just to give you pointers to start with. – brain Jul 29 '15 at 16:37
• Appreciate it! I'll see what I can come up with and come back if I can't figure anything out. – djc Jul 29 '15 at 16:42