Skip to content

Instantly share code, notes, and snippets.

@map0logo
Created September 13, 2021 02:44
Show Gist options
  • Save map0logo/802507f583e52682086987f41a469e44 to your computer and use it in GitHub Desktop.
Save map0logo/802507f583e52682086987f41a469e44 to your computer and use it in GitHub Desktop.
VigenereCipher encode and decode strings using the vigenère cipher #Scala #BigBookPython #qu4nt
import scala.io.StdIn.readLine
import collection.mutable.ListBuffer
object VigenereCipher extends App {
def encryptMessage(message: String, key: String): String = {
translateMessage(message, key, "encrypt")
}
def decryptMessage(message: String, key: String): String = {
translateMessage(message, key, "decrypt")
}
def translateMessage(message: String, key: String, mode: String): String = {
var translated: ListBuffer[String] = ListBuffer() // Stores the encrypted/decrypted message string.
val letters = ('A' to 'Z').mkString
var keyIndex: Integer = 0
val key_ = key.toUpperCase
for (symbol <- message) { // Loop through each character in message.
var num = letters.indexOf(symbol.toString.toUpperCase)
if (num != -1) { // -1 means symbol.indexOf was not in LETTERS.
if (mode == "encrypt")
// Add if encrypting:
num += letters.indexOf(key_(keyIndex))
else if (mode == "decrypt")
// Subtract if decrypting:
num -= letters.indexOf(key_(keyIndex))
if (num >= 0) num %= letters.length // Handle the potential wrap-around.
else num = letters.length - num
// Add the encrypted/decrypted symbol to translated.
if (symbol.isUpper)
translated += letters(num).toString
translated += letters(num).toString.toLowerCase
keyIndex += 1 // Move to the next letter in the key.
if (keyIndex == key_.length)
keyIndex = 0
} else
// Just add the symbol without encrypting/decrypting:
translated += symbol.toString
}
translated.mkString
}
def main: Unit = {
println("""Vigenère Cipher, by Al Sweigart al@inventwithpython.com
The Vigenère cipher is a polyalphabetic substitution cipher that was
powerful enough to remain unbroken for centuries.""")
var continue: Boolean = true
var myMode: String = ""
var myKey: String = ""
var myMessage: String = ""
var response: String = ""
var translated: String = ""
while (continue) { // Keep asking until the user enters e or d.
println("Do you want to (e)ncrypt or (d)ecrypt?")
response = readLine("> ").toLowerCase
if (response.startsWith("e")) {
myMode = "encrypt"
continue = false
} else if (response.startsWith("d")) {
myMode = "decrypt"
continue = false
} else {
println("Please enter the letter e or d.")
}
}
continue = true
while (continue) { // Keep asking until the user enters a valid key.
print("Please specify the key to use.")
print("It can be a word or any combination of letters:")
response = readLine("> ").toUpperCase
if (response.forall(_.isLetter)) {
myKey = response
continue = false
}
}
// Let the user specify the message to encrypt/decrypt:
println(s"Enter the message to $myMode.")
myMessage = readLine("> ")
// Perform the encryption/decryption:
if (myMode == "encrypt")
translated = encryptMessage(myMessage, myKey)
else if (myMode == "decrypt")
translated = decryptMessage(myMessage, myKey)
println(s"${myMode.split(' ').map(_.capitalize).mkString(" ")} message:")
println(translated)
}
main
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment