73 lines
2.2 KiB
Rust
73 lines
2.2 KiB
Rust
|
|
use std::{iter, ops::Add};
|
||
|
|
use crate::message::{self, Message};
|
||
|
|
|
||
|
|
pub fn encrypt_message(message: &mut Message, circle_length: &usize) -> Vec<Circle> {
|
||
|
|
fill_circles(
|
||
|
|
&mut encode_circles(
|
||
|
|
&mut triples_into_circles(&message.to_triples(), circle_length),
|
||
|
|
&mut message.parts.start_shift,
|
||
|
|
),
|
||
|
|
circle_length
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
fn caesar_shift(char: char, shift: u8) -> char {
|
||
|
|
(char as u8 + shift) as char
|
||
|
|
}
|
||
|
|
|
||
|
|
type Circle = Vec<message::Triple>;
|
||
|
|
|
||
|
|
fn triples_into_circles(triples: &Vec<message::Triple>, circle_length: &usize) -> Vec<Circle> {
|
||
|
|
triples.chunks(*circle_length)
|
||
|
|
.map(|chunk| {
|
||
|
|
chunk.to_vec()
|
||
|
|
}).collect()
|
||
|
|
}
|
||
|
|
|
||
|
|
fn encode_circles(circles: &mut Vec<Circle>, shift: &mut u8) -> Vec<Circle> {
|
||
|
|
circles.iter_mut().enumerate().map(|(count, circle)| {
|
||
|
|
let shift_delta = match count {
|
||
|
|
count if count % 2 == 0 => count.add(1) as i8,
|
||
|
|
_ => -(count.add(1) as i8)
|
||
|
|
};
|
||
|
|
|
||
|
|
let circle_iter = circle.iter_mut();
|
||
|
|
|
||
|
|
let new_circle = match count {
|
||
|
|
0 => circle_iter.skip(1),
|
||
|
|
_ => circle_iter.skip(0),
|
||
|
|
}.map(|triple| {
|
||
|
|
triple.first = caesar_shift(triple.first, *shift);
|
||
|
|
*shift = shift.wrapping_add_signed(shift_delta);
|
||
|
|
triple.second = caesar_shift(triple.second, *shift);
|
||
|
|
*shift = shift.wrapping_add_signed(shift_delta);
|
||
|
|
triple.second = caesar_shift(triple.third, *shift);
|
||
|
|
*shift = shift.wrapping_add_signed(shift_delta);
|
||
|
|
|
||
|
|
triple.clone()
|
||
|
|
}).collect::<Circle>();
|
||
|
|
|
||
|
|
let new_circle = match count {
|
||
|
|
0 => {
|
||
|
|
let mut vec = vec![circle[0].clone()];
|
||
|
|
vec.extend(new_circle);
|
||
|
|
return vec;
|
||
|
|
},
|
||
|
|
_ => new_circle,
|
||
|
|
};
|
||
|
|
|
||
|
|
new_circle
|
||
|
|
}).collect()
|
||
|
|
}
|
||
|
|
|
||
|
|
fn fill_circles(circles: &mut Vec<Circle>, circle_length: &usize) -> Vec<Circle> {
|
||
|
|
circles.iter_mut().map(|circle| {
|
||
|
|
circle.extend(iter::repeat(message::Triple::filler())
|
||
|
|
.take(
|
||
|
|
circle_length - circle.len()
|
||
|
|
)
|
||
|
|
);
|
||
|
|
circle.clone()
|
||
|
|
}).collect()
|
||
|
|
}
|