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}