Created
September 9, 2021 12:30
-
-
Save Linus-Albertus/a1adc60643f7580d2630fe4c61c535d2 to your computer and use it in GitHub Desktop.
[Vigenère] #Scala #BigBookPython #qu4nt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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