Skip to content

Commit a3a5226

Browse files
authored
Add Rail Fence Encryption (TheAlgorithms#476)
1 parent 1a29048 commit a3a5226

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

src/ciphers/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod hashing_traits;
88
mod kerninghan;
99
mod morse_code;
1010
mod polybius;
11+
mod rail_fence;
1112
mod rot13;
1213
mod salsa;
1314
mod sha256;
@@ -17,7 +18,6 @@ mod theoretical_rot13;
1718
mod transposition;
1819
mod vigenere;
1920
mod xor;
20-
2121
pub use self::aes::{aes_decrypt, aes_encrypt, AesKey};
2222
pub use self::another_rot13::another_rot13;
2323
pub use self::base64::{base64_decode, base64_encode};
@@ -29,6 +29,7 @@ pub use self::hashing_traits::HMAC;
2929
pub use self::kerninghan::kerninghan;
3030
pub use self::morse_code::{decode, encode};
3131
pub use self::polybius::{decode_ascii, encode_ascii};
32+
pub use self::rail_fence::{rail_fence_decrypt, rail_fence_encrypt};
3233
pub use self::rot13::rot13;
3334
pub use self::salsa::salsa20;
3435
pub use self::sha256::SHA256;

src/ciphers/rail_fence.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// wiki: https://en.wikipedia.org/wiki/Rail_fence_cipher
2+
pub fn rail_fence_encrypt(plain_text: &str, key: usize) -> String {
3+
let mut cipher = vec![Vec::new(); key];
4+
5+
for (c, i) in plain_text.chars().zip(zigzag(key)) {
6+
cipher[i].push(c);
7+
}
8+
9+
return cipher.iter().flatten().collect::<String>();
10+
}
11+
12+
pub fn rail_fence_decrypt(cipher: &str, key: usize) -> String {
13+
let mut indices: Vec<_> = zigzag(key).zip(1..).take(cipher.len()).collect();
14+
indices.sort();
15+
16+
let mut cipher_text: Vec<_> = cipher
17+
.chars()
18+
.zip(indices)
19+
.map(|(c, (_, i))| (i, c))
20+
.collect();
21+
22+
cipher_text.sort();
23+
return cipher_text.iter().map(|(_, c)| c).collect();
24+
}
25+
26+
fn zigzag(n: usize) -> impl Iterator<Item = usize> {
27+
(0..n - 1).chain((1..n).rev()).cycle()
28+
}
29+
30+
#[cfg(test)]
31+
mod test {
32+
use super::*;
33+
#[test]
34+
fn rails_basic() {
35+
assert_eq!(rail_fence_encrypt("attack at once", 2), "atc toctaka ne");
36+
assert_eq!(rail_fence_decrypt("atc toctaka ne", 2), "attack at once");
37+
38+
assert_eq!(rail_fence_encrypt("rust is cool", 3), "r cuti olsso");
39+
assert_eq!(rail_fence_decrypt("r cuti olsso", 3), "rust is cool");
40+
}
41+
}

0 commit comments

Comments
 (0)