kryptos/ciphers/
rot13.rs

1/// ROT13 Cipher
2///
3/// The struct is generated through the new() function.
4///
5pub struct Rot13 {}
6
7impl Rot13 {
8    /// Initializes a rot13 cipher with a supplied rotation.
9    ///
10    /// # Examples
11    ///
12    /// ```
13    /// use kryptos::ciphers::rot13::Rot13;
14    ///
15    /// let c = Rot13::new().unwrap();
16    /// ```
17    ///
18    pub fn new() -> Result<Self, String> {
19        Ok(Rot13 {})
20    }
21
22    /// Enciphers a message with a rot13 cipher.
23    ///
24    /// # Examples
25    ///
26    /// ```
27    /// use kryptos::ciphers::rot13::Rot13;
28    ///
29    /// let c = Rot13::new().unwrap();
30    /// assert_eq!("guvf vf n frperg", c.encipher("this is a secret").unwrap());
31    /// ```
32    ///
33    pub fn encipher(&self, plaintext: &str) -> Result<String, &'static str> {
34        Rot13::shift(plaintext, 13)
35    }
36
37    /// Deciphers a message with a rot13 cipher.
38    ///
39    /// # Examples
40    ///
41    /// ```
42    /// use kryptos::ciphers::rot13::Rot13;
43    ///
44    /// let c = Rot13::new().unwrap();
45    /// assert_eq!("this is a secret", c.decipher("guvf vf n frperg").unwrap());
46    /// ```
47    ///
48    pub fn decipher(&self, ciphertext: &str) -> Result<String, &'static str> {
49        Rot13::shift(ciphertext, 13)
50    }
51
52    // Shifts letters in a message by a given rotation.
53    //
54    fn shift(text: &str, rot: u8) -> Result<String, &'static str> {
55        Ok(text
56            .chars()
57            .map(|c| match c as u8 {
58                65..=90 => (((c as u8 - 65 + rot) % 26) + 65) as char,
59                97..=122 => (((c as u8 - 97 + rot) % 26) + 97) as char,
60                _ => c,
61            })
62            .collect::<String>())
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::Rot13;
69
70    #[test]
71    fn encipher() {
72        let c = Rot13::new().unwrap();
73        assert_eq!("guvf vf n frperg", c.encipher("this is a secret").unwrap());
74    }
75
76    #[test]
77    fn decipher() {
78        let c = Rot13::new().unwrap();
79        assert_eq!("this is a secret", c.decipher("guvf vf n frperg").unwrap());
80    }
81
82    #[test]
83    fn with_punctuation() {
84        let c = Rot13::new().unwrap();
85        assert_eq!(
86            "Uryyb, V unir n frperg",
87            c.encipher("Hello, I have a secret").unwrap()
88        );
89    }
90
91    #[test]
92    fn with_unicode() {
93        let c = Rot13::new().unwrap();
94        assert_eq!(
95            "V 🖤 pelcgbtencul",
96            c.encipher("I 🖤 cryptography").unwrap()
97        );
98    }
99}