diff --git a/src/ciphers/mod.rs b/src/ciphers/mod.rs index 1a54bf84e7f..04ec8a9c32e 100644 --- a/src/ciphers/mod.rs +++ b/src/ciphers/mod.rs @@ -8,6 +8,7 @@ mod hashing_traits; mod kerninghan; mod morse_code; mod polybius; +mod rail_fence; mod rot13; mod salsa; mod sha256; @@ -17,7 +18,6 @@ mod theoretical_rot13; mod transposition; mod vigenere; mod xor; - pub use self::aes::{aes_decrypt, aes_encrypt, AesKey}; pub use self::another_rot13::another_rot13; pub use self::base64::{base64_decode, base64_encode}; @@ -29,6 +29,7 @@ pub use self::hashing_traits::HMAC; pub use self::kerninghan::kerninghan; pub use self::morse_code::{decode, encode}; pub use self::polybius::{decode_ascii, encode_ascii}; +pub use self::rail_fence::{rail_fence_decrypt, rail_fence_encrypt}; pub use self::rot13::rot13; pub use self::salsa::salsa20; pub use self::sha256::SHA256; diff --git a/src/ciphers/rail_fence.rs b/src/ciphers/rail_fence.rs new file mode 100644 index 00000000000..aedff07ea31 --- /dev/null +++ b/src/ciphers/rail_fence.rs @@ -0,0 +1,41 @@ +// wiki: https://en.wikipedia.org/wiki/Rail_fence_cipher +pub fn rail_fence_encrypt(plain_text: &str, key: usize) -> String { + let mut cipher = vec![Vec::new(); key]; + + for (c, i) in plain_text.chars().zip(zigzag(key)) { + cipher[i].push(c); + } + + return cipher.iter().flatten().collect::(); +} + +pub fn rail_fence_decrypt(cipher: &str, key: usize) -> String { + let mut indices: Vec<_> = zigzag(key).zip(1..).take(cipher.len()).collect(); + indices.sort(); + + let mut cipher_text: Vec<_> = cipher + .chars() + .zip(indices) + .map(|(c, (_, i))| (i, c)) + .collect(); + + cipher_text.sort(); + return cipher_text.iter().map(|(_, c)| c).collect(); +} + +fn zigzag(n: usize) -> impl Iterator { + (0..n - 1).chain((1..n).rev()).cycle() +} + +#[cfg(test)] +mod test { + use super::*; + #[test] + fn rails_basic() { + assert_eq!(rail_fence_encrypt("attack at once", 2), "atc toctaka ne"); + assert_eq!(rail_fence_decrypt("atc toctaka ne", 2), "attack at once"); + + assert_eq!(rail_fence_encrypt("rust is cool", 3), "r cuti olsso"); + assert_eq!(rail_fence_decrypt("r cuti olsso", 3), "rust is cool"); + } +}