cryptatools_core/cryptography/classical/encryption/transpositional_ciphers/
columnar_transposition.rs

1use std::sync::Arc;
2
3use crate::utils::alphabets::Alphabet;
4use crate::utils::alphabets::split_bytes_by_characters_representation;
5use crate::utils::alphabets::uniffy_opcode_group;
6
7pub struct ColumnarTranspositionAlgorithm {
8    alphabet: Arc<Alphabet>,
9}
10
11impl ColumnarTranspositionAlgorithm {
12    pub fn new(alphabet: Arc<Alphabet>) -> Self {
13        ColumnarTranspositionAlgorithm { 
14            alphabet: alphabet
15         }
16    }
17    
18    /// Encrypt the `plain_text` with the columnar transposition encryption algorithm `key`.
19    ///
20    /// An array with lines of size `key` is created with the `plain_text` argument. The cipher text is producted as output with reading the plain text, column by column, from top to bot, from lefgt to right.
21    /// The custom alphabet has been put in the constructor of the struct CaesarNumberAlgorithm.
22    /// 
23    /// ```
24    /// use cryptatools_core::utils::alphabets::Alphabet;
25    /// use cryptatools_core::utils::convert::{Encode, Decode};
26    /// use cryptatools_core::cryptography::classical::encryption::transpositional_ciphers::columnar_transposition::ColumnarTranspositionAlgorithm;
27    /// 
28    /// let printable_ascii_alphabet = Alphabet::new_empty().ascii_printable_only_encoding();
29    /// let key = 6;
30    /// let plain_text = "all work and no play makes johnny a dull boy".replace(" ", "").to_uppercase();
31    /// let plain_text_opcodes = Encode::encode(&printable_ascii_alphabet, String::from(plain_text));
32    /// let mut columnar = ColumnarTranspositionAlgorithm::new(printable_ascii_alphabet.into());
33    /// let cipher_text_opcodes = columnar.encrypt(plain_text_opcodes, 6);
34    /// let ascii_plain_text = Decode::from_u8_to_ascii(cipher_text_opcodes);
35    /// 
36    /// assert_eq!(ascii_plain_text, "AKPKNLLALENLLNASYBWDYJAOONMODYROAHU");
37    /// ```
38    pub fn encrypt(&self, plain_text: Vec<u8>, key: u32) -> Vec<u8> {
39        let plain_text_group = split_bytes_by_characters_representation(&self.alphabet, plain_text);
40        let columns: Vec<Vec<u8>> = (0..key)
41            .flat_map(|collumn| (collumn..plain_text_group.len() as u32)
42                .step_by(key as usize)
43                .map(|i| plain_text_group[i as usize].clone()))
44            .collect();
45
46        uniffy_opcode_group(columns)
47    }
48    
49    /// Decrypt the `cipher_text` with the columnar transposition encryption algorithm `key`.
50    /// 
51    /// Exatcly same operation as `encrypt` method.
52    /// 
53    /// ```
54    /// use cryptatools_core::utils::alphabets::Alphabet;
55    /// use cryptatools_core::utils::convert::{Encode, Decode};
56    /// use cryptatools_core::cryptography::classical::encryption::transpositional_ciphers::columnar_transposition::ColumnarTranspositionAlgorithm;
57    ///
58    /// let printable_ascii_alphabet = Alphabet::new_empty().ascii_printable_only_encoding();
59    /// let mut columnar = ColumnarTranspositionAlgorithm::new(printable_ascii_alphabet.into());
60    /// let cipher_text_ascii = String::from("AKPKNLLALENLLNASYBWDYJAOONMODYROAHU");
61    /// let opcodes_plain_text = Encode::from_ascii_to_u8(cipher_text_ascii);
62    /// let key = 6;
63    /// let plain_text_opcodes = columnar.decrypt(opcodes_plain_text, key);
64    /// let ascii_plain_text = Decode::from_u8_to_ascii(plain_text_opcodes);
65    /// 
66    /// assert_eq!(ascii_plain_text, "all work and no play makes johnny a dull boy".replace(" ", "").to_uppercase());
67    /// ```
68    pub fn decrypt(&self, cipher_text: Vec<u8>, key: u32) -> Vec<u8> {
69        let cipher_text_group = split_bytes_by_characters_representation(&self.alphabet, cipher_text);
70        let columns: Vec<Vec<u8>> = (0..key)
71            .flat_map(|collumn| (collumn..cipher_text_group.len() as u32)
72                .step_by(key as usize)
73                .map(|i| cipher_text_group[i as usize].clone()))
74            .collect();
75
76        uniffy_opcode_group(columns)
77    }
78}