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