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}