I'm trying to implement Caesar Cipher in Rust. My tests pass for the encode function, but for the decode function, I get a warning:
|
34 | if translated_index < 0 {
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_comparisons)]` on by default
and an error
panicked at 'attempt to subtract with overflow', src/cryptography/caesar_cipher.rs:32:40
I'm not sure what's wrong with the wrap-around logic of the decode
function, because I implemented encode
in the same manner and it works.
This is the complete code:
fn caesar_encode(message: &str, key: usize) -> String {
let supported_characters = "abcdefghijklmnopqrstuvwxyz";
let mut encoded_message = String::new();
for letter in message.chars() {
if supported_characters.contains(letter) {
let letter_index = supported_characters.find(letter).unwrap();
let mut translated_index = letter_index + key;
if translated_index >= supported_characters.len() {
translated_index = translated_index - supported_characters.len() // wrap-around
}
let translated_letter = supported_characters.chars().nth(translated_index).unwrap();
encoded_message.push(translated_letter)
} else {
encoded_message.push(letter)
}
}
encoded_message
}
fn caesar_decode(message: &str, key: usize) -> String {
let supported_characters = "abcdefghijklmnopqrstuvwxyz";
let mut decoded_message = String::new();
for letter in message.chars() {
if supported_characters.contains(letter) {
let letter_index = supported_characters.find(letter).unwrap();
let mut translated_index = letter_index - key;
if translated_index < 0 {
translated_index = translated_index + supported_characters.len() // wrap-around
}
let translated_letter = supported_characters.chars().nth(translated_index).unwrap();
decoded_message.push(translated_letter)
} else {
decoded_message.push(letter)
}
}
decoded_message
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_caesar_encode() {
let data = [
("veni vidi vici", 3, "yhql ylgl ylfl"),
("hello", 10, "rovvy"),
("hello world!", 0, "hello world!"),
(
"you can show black is white by argument, but you will never convince me.",
8,
"gwc kiv apwe jtiks qa epqbm jg izocumvb, jcb gwc eqtt vmdmz kwvdqvkm um."
),
("", 5, ""),
("a", 1, "b"),
("x", 7, "e"),
("z", 1, "a"),
];
for (plaintext_message, key, expected) in data {
assert_eq!(caesar_encode(plaintext_message, key), expected)
}
}
#[test]
fn test_caesar_decode() {
let data = [
("a", 1, "z"),
("wkh txlfn eurzq ira mxpsv ryhu wkh odcb grj", 3, "the quick brown fox jumps over the lazy dog"),
("aol lultf pz ulhy", 7, "the enemy is near"),
];
for (cryptic_message, key, expected) in data {
assert_eq!(caesar_decode(cryptic_message, key), expected)
}
}
}