Vigenère cipher: Difference between revisions

→‎Alternate Scala implementation: refactored to remove usage of variables; shortened static setup of chars with for loop init; used single recursive instead of map call
m (→‎{{header|C}}: Added restrict)
(→‎Alternate Scala implementation: refactored to remove usage of variables; shortened static setup of chars with for loop init; used single recursive instead of map call)
Line 2,788:
</pre>
===Alternate Scala implementation===
This version first creates a sequence of characters from A to Z and a "flattened" Vigenere Square. It then encodes or decodes by just indexing between these two sequences. The code does no error checking, as well as encoding all lower case letters as upper case.
 
<lang scala>classobject Vigenere(val key: String) {
The code does no error checking and assumes that a valid key of 25 characters or less in length is passed to it.
 
val key = "LEMON"
Also, it will only encode or decode upper case characters in the range A to Z passing any other character through unchanged.
private val chars = 'A' to 'Z'
 
<lang scala>class Vigenere(val key: String) {
 
private def rotate(p: Int, s: IndexedSeq[Char]) = s.drop(p) ++ s.take(p)
val vSquare = (for (i <- Range(0, 25)) yield rotate(i, chars)).flatten
 
def encrypt(s: String) = enrOrDecode(0, s.toUpperCase, encode)
private val chars = 'A' to 'Z'
def decrypt(s: String) = enrOrDecode(0, s.toUpperCase, decode)
 
private def enrOrDecode(i: Int , in: String, op:(Char, Int) => Char): String = {
private val vSquare = (chars ++
if (in.length == 0) in else {
rotate(1, chars) ++
val index = if (i == key.length) 0 else rotate(2, chars) ++i
(if (chars.contains(in.head)) op(in.head, index) else in.head) + enrOrDecode(index + 1, in.tail, op)
rotate(3, chars) ++
} else c
rotate(4, chars) ++
}
rotate(5, chars) ++
rotate(6, chars) ++
rotate(7, chars) ++
rotate(8, chars) ++
rotate(9, chars) ++
rotate(10, chars) ++
rotate(11, chars) ++
rotate(12, chars) ++
rotate(13, chars) ++
rotate(14, chars) ++
rotate(15, chars) ++
rotate(16, chars) ++
rotate(17, chars) ++
rotate(18, chars) ++
rotate(19, chars) ++
rotate(20, chars) ++
rotate(21, chars) ++
rotate(22, chars) ++
rotate(23, chars) ++
rotate(24, chars) ++
rotate(25, chars))
 
private var encIndex = -1
private var decIndex = -1
 
private def encode(c: Char, index: Int): Char = {
if (chars.contains(c)) vSquare((c - 'A') * 26 + key(encIndexindex) - 'A') else c
encIndex += 1
if (encIndex == key.length) encIndex = 0
if (chars.contains(c)) vSquare((c - 'A') * 26 + key(encIndex) - 'A') else c
}
 
private def decode(c: Char, index: Int) = {
val baseIndex = (key(decIndexindex) - 'A') * 26
decIndex += 1
if (decIndex == key.length) decIndex = 0
if (chars.contains(c)) {
val baseIndex = (key(decIndex) - 'A') * 26
val nextIndex = vSquare.indexOf(c, baseIndex)
chars(nextIndex - baseIndex)
} else c
}
}
}</lang>
 
<lang scala>val text = "ATTACKATDAWN"
val myVigenereencoded = new Vigenere.encrypt("LEMON"text)
val decoded = Vigenere.decrypt(text)
val encoded = text.map(c => myVigenere.encode(c))
println("PlaintextPlain text => " + text)
println("CiphertextCipher text => " + encoded)
println("Decrypted => " + encoded.map(c => myVigenere.decode(c))decoded)</lang>
 
{{out}}
<pre>Plaintextplain text => ATTACKATDAWN
Ciphertextcipher text => LXFOPVEFRNHR
Decrypteddecrypted => ATTACKATDAWN</pre>
 
=={{header|Seed7}}==
Anonymous user