-
Notifications
You must be signed in to change notification settings - Fork 74
/
caesar.rs
60 lines (56 loc) · 1.45 KB
/
caesar.rs
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
/// Implements the Caesar Cipher based on cipher_crypt::caesar
///
/// Rotates each ascii character by shift.
/// The most basic example is ROT 13, which rotates 'a' to 'n'.
/// This implementation does not rotates unicode characters.
///
/// See [Caesar cipher](https://en.wikipedia.org/wiki/Caesar_cipher) for more information.
///
/// # Arguments
///
/// *`cipher` - A [`&str`] plain text to encrypt.
/// *`shift` - Amount to right-shift the text.
///
/// # Returns
///
/// An owned [`String`] of the encrypted text.
///
/// # Examples
///
/// ```rust
/// # use rust_algorithms::ciphers::caesar;
///
/// let encoded = caesar("one sheep two sheep", 3);
///
/// assert_eq!(encoded, "rqh vkhhs wzr vkhhs")
/// ```
pub fn caesar(cipher: &str, shift: u8) -> String {
cipher
.chars()
.map(|c| {
if c.is_ascii_alphabetic() {
let first = if c.is_ascii_lowercase() { b'a' } else { b'A' };
// modulo the distance to keep character range
(first + (c as u8 + shift - first) % 26) as char
} else {
c
}
})
.collect()
}
#[cfg(test)]
mod tests {
use super::caesar;
#[test]
fn empty() {
assert_eq!(caesar("", 13), "");
}
#[test]
fn caesar_rot_13() {
assert_eq!(caesar("rust", 13), "ehfg");
}
#[test]
fn caesar_unicode() {
assert_eq!(caesar("attack at dawn 攻", 5), "fyyfhp fy ifbs 攻");
}
}