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:


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.
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 &lt;- 0 to 25) {
        for (col &lt;- 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 &lt;- text.zipWithIndex) yield c match {
            case (c, i) =&gt; 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 &lt;- text.zipWithIndex) yield c match {
        case (' ', _) =&gt; ' '
        case (c, i)   =&gt; 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?