cipher_salad/cipher/
atbash.rs1use crate::{Alphabet, ForeignGraphemesPolicy};
2use unicode_segmentation::UnicodeSegmentation;
3
4pub struct Atbash {
5 foreign_policy: ForeignGraphemesPolicy,
6 alphabet: Alphabet,
7}
8
9impl Atbash {
10 #[must_use]
11 pub fn new(alphabet: Alphabet, foreign_policy: ForeignGraphemesPolicy) -> Self {
12 Self {
13 foreign_policy,
14 alphabet,
15 }
16 }
17
18 fn cipher(&self, contents: &str) -> String {
19 contents
20 .graphemes(true)
21 .map(|grapheme| (grapheme, self.alphabet.index_of(grapheme)))
22 .filter_map(|(grapheme, index)| match index {
23 Some(grapheme_index) => {
24 let ciphered_index = -(grapheme_index as isize + 1);
25 let ciphered_index = ciphered_index.rem_euclid(self.alphabet.length() as isize);
26 self.alphabet.grapheme_at(ciphered_index as usize).cloned()
27 }
28 None => match self.foreign_policy {
29 ForeignGraphemesPolicy::Include => Some(grapheme.to_string()),
30 ForeignGraphemesPolicy::Exclude => Some(String::new()),
31 },
32 })
33 .collect()
34 }
35
36 #[must_use]
37 pub fn encrypt(&self, contents: &str) -> String {
38 self.cipher(contents)
39 }
40
41 #[must_use]
42 pub fn decrypt(&self, ciphertext: &str) -> String {
43 self.cipher(ciphertext)
44 }
45}