init. encoding
This commit is contained in:
commit
f7950b903b
|
|
@ -0,0 +1,72 @@
|
|||
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()
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
use clap::{Parser, Subcommand};
|
||||
use std::path::PathBuf;
|
||||
|
||||
mod message;
|
||||
mod encoding;
|
||||
|
||||
pub use message::Message;
|
||||
pub use encoding::encrypt_message;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(version, about, long_about = None)]
|
||||
pub struct Args {
|
||||
#[command(subcommand)]
|
||||
pub mode: Mode,
|
||||
#[arg(short, long)]
|
||||
pub message: String,
|
||||
#[arg(short, long)]
|
||||
pub start_shift: String,
|
||||
#[arg(short, long)]
|
||||
pub circle_length: usize,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum Mode {
|
||||
Gui,
|
||||
Display,
|
||||
Save {
|
||||
#[arg(short, long)]
|
||||
path: PathBuf
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
use circle_cipher:: {
|
||||
encrypt_message,
|
||||
Message
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let mut msg = Message::new("Hello".to_string(), 12);
|
||||
let circles = encrypt_message(&mut msg, &127);
|
||||
|
||||
println!("{:?}", circles)
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
use std::vec::IntoIter;
|
||||
|
||||
|
||||
pub struct Message {
|
||||
pub parts: Parts,
|
||||
pub combined: String,
|
||||
}
|
||||
impl Message {
|
||||
pub fn new(content: String, start_shift: u8) -> Self {
|
||||
let parts = Parts::new(content, start_shift);
|
||||
let combined = parts.shift_to_string() + &parts.content;
|
||||
Self {
|
||||
parts,
|
||||
combined,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_triples(&self) -> Vec<Triple> {
|
||||
self.combined.chars()
|
||||
.collect::<Vec<char>>()
|
||||
.chunks(3)
|
||||
.filter_map(|chunk| {
|
||||
Some(Triple::new(chunk[0], chunk[1], chunk[2]))
|
||||
}
|
||||
).collect()
|
||||
}
|
||||
}
|
||||
pub struct Parts {
|
||||
pub content: String,
|
||||
pub start_shift: u8,
|
||||
}
|
||||
impl Parts {
|
||||
fn new(content: String, start_shift: u8) -> Self {
|
||||
let mut parts = Self {
|
||||
content,
|
||||
start_shift,
|
||||
};
|
||||
parts.standardize();
|
||||
|
||||
parts
|
||||
}
|
||||
|
||||
fn standardize(&mut self) {
|
||||
let delta = self.content.len() % 3;
|
||||
match delta {
|
||||
0 => (),
|
||||
_ => { self.content += &"_".repeat(3 - delta) },
|
||||
}
|
||||
}
|
||||
|
||||
fn shift_to_string(&self) -> String {
|
||||
let string = self.start_shift.to_string();
|
||||
"0".repeat(3 - string.len()) + &string
|
||||
}
|
||||
}
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Triple {
|
||||
pub first: char,
|
||||
pub second: char,
|
||||
pub third: char
|
||||
}
|
||||
impl Triple {
|
||||
fn new(first: char, second: char, third: char) -> Self {
|
||||
Self {
|
||||
first,
|
||||
second,
|
||||
third,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn filler() -> Self {
|
||||
let filler = 0 as char;
|
||||
Self {
|
||||
first: filler,
|
||||
second: filler,
|
||||
third: filler,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl IntoIterator for Triple {
|
||||
type Item = char;
|
||||
type IntoIter = IntoIter<char>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
vec![self.first, self.second, self.third].into_iter()
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue