Skip to content

Instantly share code, notes, and snippets.

@Linus-Albertus
Created September 9, 2021 12:30
Show Gist options
  • Save Linus-Albertus/a1adc60643f7580d2630fe4c61c535d2 to your computer and use it in GitHub Desktop.
Save Linus-Albertus/a1adc60643f7580d2630fe4c61c535d2 to your computer and use it in GitHub Desktop.
[Vigenère] #Scala #BigBookPython #qu4nt
/* Vigenère Cipher, by Lino Urdaneta and Al Sweigart al@inventwithpython.com
The Vigenère cipher is a polyalphabetic substitution cipher that was
powerful enough to remain unbroken for centuries.
More info at: https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher
Tags: short, cryptography, math
*/
object Vigenere {
def main(): Unit = {
println("""Vigenère Cipher.
The Vigenère cipher is a polyalphabetic substitution cipher that was
powerful enough to remain unbroken for centuries.""".stripMargin)
println("Choice (e)ncrypt of (d)ecrypt:")
val choice: String = scala.io.StdIn.readLine("> ")
if (choice == "e") {
val message = new EncryptMessage
println(message.myTranslation)
}
else if (choice == "d") {
val message = new DecryptMessage
println(message.myTranslation)
}
else println("Command not recognized.")
}
}
abstract class CodingMessage {
// Protected values (not accessible outside class or subclass)
protected val letters: String = "ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"
protected val messageObject = new InputMessage
protected val keyObject = new InputKey
val myMessage: String = messageObject.message
val myKey: String = keyObject.key
// Stores the encrypted/decrypted message, character by character in a vector:
protected var transVector: Vector[String] = Vector[String]()
// Abstract method:
def translateMyMessage(message: String, key: String): String
/**
* Perform the encryption/decryption.
* It is an abstract class.
*/
}
class InputMessage {
println("Enter the message to encrypt/decrypt:")
val message: String = scala.io.StdIn.readLine("> ")
/**
* Requests a message from the user.
*/
}
class InputKey {
var key: String = ""
private var validKey: Boolean = false
// The loop only ends with a valid key (only letters):
while (!validKey) {
println(
"""Please specify the key to use.
|It can be a word or any combination of letters:
|""".stripMargin)
key = scala.io.StdIn.readLine("> ").toUpperCase() // To uppercase.
if (key.forall(_.isLetter)) validKey = true
}
/**
* Requests a valid key from the user and checks its format
* (only letters).
*/
}
class EncryptMessage extends CodingMessage {
val myTranslation: String = translateMyMessage()
def translateMyMessage(message: String = myMessage, key: String = myKey): String = {
var keyIndex: Int = 0
for (c <- message) {
var num: Int = letters.indexOf(c.toUpper)
if (num != -1) {
num += letters.indexOf(key(keyIndex))
num %= letters.length
if (c.isUpper) transVector = transVector :+ letters(num).toString
else if (c.isLower) transVector = transVector :+ letters(num).toLower.toString
keyIndex += 1
if (keyIndex == key.length) keyIndex = 0
}
else {
transVector = transVector :+ c.toString
}
}
val translated = transVector.mkString
translated
/**
* Returns a string with the encrypted message.
* Take as parameters the message and the key.
*/
}
/**
* Text to encrypted message. Subclass of CodingMessage.
*/
}
class DecryptMessage extends CodingMessage {
val myTranslation: String = translateMyMessage()
def translateMyMessage(message: String = myMessage, key: String = myKey): String = {
var keyIndex: Int = 0
for (c <- message) {
var num: Int = letters.indexOf(c.toUpper)
if (num != -1) {
num -= letters.indexOf(key(keyIndex))
if (num < 0) num = (num % letters.length) + letters.length
if (num >= 0) num %= letters.length
// The modulo operator works different in Scala for negative numerator:
if (c.isUpper) transVector = transVector :+ letters(num).toString
else if (c.isLower) transVector = transVector :+ letters(num).toLower.toString
keyIndex += 1
if (keyIndex == key.length) keyIndex = 0
}
else {
transVector = transVector :+ c.toString
}
}
val translated = transVector.mkString
translated
/**
* Returns a string with the decrypted message.
* Take as parameters the message and the key.
*/
}
/**
* Encrypted message to text. Subclass of CodingMessage.
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment