Cipher: Spartan Scytale
The Spartan Scytale was communication device used by the military of Sparta.
The Scytale is an example of a transposition cipher and it dates from around 500 B.C. .
The Ciphering Process
- Setup:
The sender of the message takes a strip of parchement (paper) and wrapps it around a cylindrical rod. - Write plaintext message:
The sender writes the message line by line, and parallel to the rod’s axis.This way, successive letters in a word are spread out across successive turns of the parchment. - Send Message:
The sender removes the parchment from the rod. A messenger is tasked with delivering the strip (message) to the intended receiver.
Any enemy intercepting the messenger, and examining the strip, would only see a strip of jumpled letters. Without the rod it’s hard to decipher the message. - Decipher:
The messenger delivers the strip to the receiver of the message. The receiver deciphers the message by wrapping the strip around a scytale of his own and can now read the plaintext message.
A Simple Code Example
Let’s try to write a simple Spartan Scytale cipher program.
The following program makes a lot of assumptions on the input provided to the ciphering function. The program is only meant to illustrate the fundamental idea of the cipher.
1
2struct Scytale {
3 turns: usize,
4 lines: usize,
5}
6
7impl Scytale {
8 fn new(t: usize, l: usize) -> Self {
9 Scytale {
10 turns: t,
11 lines: l,
12 }
13 }
14
15 fn encipher(&self, message: &str) -> String {
16 let mut scytale_strip: Vec<char> = Vec::with_capacity(message.len());
17 for _ in 0..message.len() {
18 scytale_strip.push('-');
19 }
20
21 let mut chars = message.chars();
22 for line in 0..self.lines {
23 for turn in 0..self.turns {
24 scytale_strip[turn * self.lines + line] = chars.next().unwrap();
25 }
26 }
27
28 scytale_strip.into_iter().collect::<String>()
29 }
30
31 fn decipher(&self, ciphertext: &str) -> String {
32 let mut scytale_strip: Vec<char> = Vec::new();
33
34 for line in 0..self.lines {
35 for (i, c) in ciphertext.chars().enumerate() {
36 if i % self.lines == line {
37 scytale_strip.push(c);
38 }
39 }
40 }
41
42 scytale_strip.iter().collect::<String>()
43 }
44}
45
46fn main() {
47 let scytale = Scytale::new(5,3);
48 println!("{}", scytale.encipher("abcdefghijklmno"));
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54 #[test]
55 fn encipher_test() {
56 let scytale = Scytale::new(5,3);
57 assert_eq!(scytale.encipher("abcdefghijklmno"), "afkbglchmdinejo");
58 }
59
60 #[test]
61 fn decipher_test() {
62 let scytale = Scytale::new(5,3);
63 assert_eq!(scytale.decipher("afkbglchmdinejo"), "abcdefghijklmno");
64 }
65}