cryptatools_core/cryptography/classical/encryption/monoalphabetic_ciphers/
caesar_number.rs

1//! Encrypt with Caesar shifting encryption algorithm.
2use std::sync::Arc;
3use crate::utils::alphabets::Alphabet;
4use crate::utils::alphabets;
5
6pub struct CaesarNumberAlgorithm {
7    /// Alphabet used by the caesar number encryption Algotithm.
8    pub alphabet: Arc<Alphabet>,
9}
10
11impl CaesarNumberAlgorithm {
12    pub fn new(alphabet: Arc<Alphabet>) -> Self {
13        CaesarNumberAlgorithm {
14            alphabet
15        }
16    }
17
18     ///  Encrypt the plain text with the caesar number encryption algorithm. Does not care of the alphabet.
19     ///
20     ///  The `plain_text` is passed as argument. Each character in the `plain_text` is shifted of `key` ranges in his opcode representation.
21     ///  If the alphabet overflows, then the cipher text continues from the start of the alphabet.
22     ///  The custom alphabet has been put in the constructor of the struct CaesarNumberAlgorithm.
23     /// 
24     ///  ```
25     ///  use cryptatools_core::cryptography::classical::encryption::monoalphabetic_ciphers::caesar_number::CaesarNumberAlgorithm;
26     ///  use cryptatools_core::utils::alphabets::Alphabet;
27     ///  
28     ///  let ascii_alphabet = Alphabet::new_empty().ascii_encoding();
29     ///  let mut c: CaesarNumberAlgorithm = CaesarNumberAlgorithm::new(ascii_alphabet.into());
30     ///  let encrypted = c.encrypt_by_opcode_shift(vec![0x41, 0x41, 0x41], 1);
31     ///  assert_eq!(vec![0x42, 0x42, 0x42], encrypted);
32     ///  ```
33     /// 
34     ///  ```
35     ///  use cryptatools_core::cryptography::classical::encryption::monoalphabetic_ciphers::caesar_number::CaesarNumberAlgorithm;
36     ///  use cryptatools_core::utils::alphabets::Alphabet;
37     ///  use std::char;
38     /// 
39     ///  let ascii_alphabet = Alphabet::new_empty().ascii_encoding();
40     ///  let mut c: CaesarNumberAlgorithm = CaesarNumberAlgorithm::new(ascii_alphabet.into());
41     ///  let plain_text: Vec<u8> = vec![0x41, 0x41, 0x41];
42     ///  let encrypted = c.encrypt_by_opcode_shift(plain_text, 1);
43     ///  let mut re_encrypted = String::new();
44     ///  for character_int in encrypted {
45     ///      re_encrypted.push(character_int.into());
46     ///  }
47     ///  assert_eq!(re_encrypted, "BBB");
48     ///  ```
49     /// 
50     ///  ```
51     ///  use cryptatools_core::cryptography::classical::encryption::monoalphabetic_ciphers::caesar_number::CaesarNumberAlgorithm;
52     ///  use cryptatools_core::utils::alphabets::Alphabet;
53     ///  use std::char;
54     /// 
55     ///  let printable_chars_of_ascii_characters = Alphabet::new_empty().ascii_printable_only_encoding();
56     ///  let mut c: CaesarNumberAlgorithm = CaesarNumberAlgorithm::new(printable_chars_of_ascii_characters.into());
57     ///  let plain_text: Vec<u8> = vec![0x41, 0x41, 0x41];
58     ///  let encrypted = c.encrypt_by_opcode_shift(plain_text, 10);
59     ///  let mut re_encrypted = String::new();
60     ///  for character_int in encrypted {
61     ///      re_encrypted.push(character_int.into());
62     ///  }
63     ///  assert_eq!(re_encrypted, "KKK");
64     ///  ```
65     pub fn encrypt_by_opcode_shift(&self, plain_text: Vec<u8>, key: u32) -> Vec<u8> {
66        let mut result: Vec<u8> = Vec::new();
67
68        for element in plain_text {
69            let character: u8 = ((element as u32 + key) % 255 as u32) as u8;
70            result.push(character);
71        }
72
73        return result;
74    }
75
76     ///  Decrypt the cipher text with the caesar number encryption algorithm. Does not care of the alphabet.
77     ///
78     ///  The `cipher_text` is passed as argument. Each character in the `cipher_text` is itself minus `key`.
79     ///  If the alphabet overflows, then the cipher text continues from the end of the alphabet.
80     ///  The custom alphabet has been put in the constructor of the struct CaesarNumberAlgorithm.
81     /// 
82     ///  ```
83     ///  use cryptatools_core::cryptography::classical::encryption::monoalphabetic_ciphers::caesar_number::CaesarNumberAlgorithm;
84     ///  use cryptatools_core::utils::alphabets::Alphabet;
85     ///  
86     ///  let ascii_alphabet = Alphabet::new_empty().ascii_encoding();
87     ///  let mut c: CaesarNumberAlgorithm = CaesarNumberAlgorithm::new(ascii_alphabet.into());
88     ///  let encrypted = c.encrypt_by_opcode_shift(vec![0x41, 0x41, 0x41], 1);
89     ///  assert_eq!(vec![0x42, 0x42, 0x42], encrypted);
90     ///  ```
91    pub fn decrypt_by_opcode_shift(&self, cipher_text: Vec<u8>, key: u32) -> Vec<u8> {
92        let mut result: Vec<u8> = Vec::new();
93
94        for element in cipher_text {
95            let character: u8 = ((element as u32 - key) % 255 as u32) as u8;
96            result.push(character);
97        }
98
99        return result;
100    }
101
102     ///  Encrypt the plain text with the caesar number encryption algorithm.
103     ///
104     ///  The `plain_text` is passed as argument. Each character in the `plain_text` is shifted of `key` ranges in the alphabet.
105     ///  If the alphabet overflows, then the cipher text continues from the start of the alphabet.
106     ///  The custom alphabet has been put in the constructor of the struct CaesarNumberAlgorithm.
107     /// 
108    pub fn encrypt_by_alphabet_shift(&self, plain_text: Vec<u8>, key: u32) -> Vec<u8> {
109        let plain_unified_opcodes = alphabets::split_bytes_by_characters_representation(&self.alphabet, plain_text.clone());
110        let mut cipher_unified_opcodes = vec![];
111        let ordered_alphabet = self.alphabet.get_encoding();
112
113        for opcode in plain_unified_opcodes {
114            let plain_text_position: u32 = ordered_alphabet.iter().position(|opcodes_key| opcodes_key.bytes == opcode).unwrap() as u32;
115            let cipher_text_position: u32 = (plain_text_position + key) % (self.alphabet.get_encoding().len() as u32);
116
117            cipher_unified_opcodes.push(ordered_alphabet[cipher_text_position as usize].bytes.clone());
118        }
119
120        alphabets::uniffy_opcode_group(cipher_unified_opcodes)
121    }
122}
123
124#[cfg(test)]
125mod tests {
126    use super::*;
127
128    #[test]
129    fn encrypt_with_caesar_number_encryption_algorithm() {
130        let ascii = alphabets::Alphabet::new(vec![]).ascii_printable_only_encoding();
131        let c = CaesarNumberAlgorithm::new(Arc::new(ascii));
132        let encrypted = c.encrypt_by_opcode_shift(vec![0x42, 0x42, 0x42], 1);
133        assert_eq!(vec![0x43, 0x43, 0x43], encrypted);
134    }
135}