cipher_crypt/rot13.rs
1//! ROT13 ("rotate by 13 places"), is a simple implementation of the Caesar cipher. It substitutes
2//! a letter with the one 13 places after it in the alphabet.
3//!
4//! ROT13 is its own inverse. That is, `ROT13(ROT13(message)) = message`. Due to its simplicity,
5//! this module does not implement the `Cipher` trait.
6//!
7use crate::common::alphabet::Alphabet;
8use crate::common::{alphabet, substitute};
9
10/// Encrypt a message using the Rot13 substitute cipher.
11///
12/// # Examples
13/// Basic usage:
14///
15/// ```
16/// use cipher_crypt::Rot13;
17///
18/// let m = "I am my own inverse";
19/// assert_eq!(m, &Rot13::decrypt(&Rot13::encrypt(m)));
20/// ```
21///
22pub fn encrypt(message: &str) -> String {
23 substitute::shift_substitution(message, |i| alphabet::STANDARD.modulo((i + 13) as isize))
24}
25
26/// Decrypt a message using the Rot13 substitute cipher.
27///
28/// # Examples
29/// Basic usage:
30///
31/// ```
32/// use cipher_crypt::Rot13;
33///
34/// let m = "I am my own inverse";
35/// assert_eq!(m, &Rot13::decrypt(&Rot13::encrypt(m)));
36/// ```
37///
38pub fn decrypt(message: &str) -> String {
39 substitute::shift_substitution(message, |i| alphabet::STANDARD.modulo((i + 13) as isize))
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 #[test]
47 fn with_utf8() {
48 let message = "Peace, Freedom and Liberty! 🗡️";
49 let encrypted = encrypt(message);
50 let decrypted = decrypt(&encrypted);
51
52 assert_eq!(decrypted, message);
53 }
54
55 #[test]
56 fn alphabet_encrypt() {
57 let message = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
58
59 let encrypted = encrypt(message);
60 let decrypted = decrypt(&encrypted);
61
62 assert_eq!(decrypted, message);
63 }
64}