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 61 62 63 64 65 66 67 68 69 70 71
use crate::{ cipher::{Keyed, Solve, Symmetric}, key::{IdentityKey, IoKey, Key, Keyword, PortaSquare, VigSquare}, lang::Language, }; pub struct Porta { square: PortaSquare, pub keyword: Keyword, } impl Symmetric for Porta { fn run(&self, language: &mut Language, msg: &str) -> String { let mut count = 0; msg.chars() .map(|c| { if language.is_letter(&c) { let new_cp = self.square.encrypt( self.keyword.at(count % self.keyword.len()) / 2, language.get_cp(&c), ); count += 1; language.update_cp(&c, new_cp) } else { c } }) .collect() } } impl Keyed for Porta { fn new(language: &mut Language) -> Porta { let mut result = Porta { square: PortaSquare::identity(language), keyword: Keyword::identity(language), }; result .keyword .key_info_mut() .set("Keyword", "<string>", "kw"); result } fn keys(&self) -> Vec<&dyn IoKey> { vec![&self.keyword] } fn keys_mut(&mut self) -> Vec<&mut dyn IoKey> { vec![&mut self.keyword] } } impl Solve for Porta { fn solve(&mut self, language: &mut Language, msg: &str) { let ciphertext = language.string_to_vec(msg); self.keyword .set( language, crate::cipher::polyalph::vig_solve( &ciphertext, 2, language, |cp, shift| self.square.encrypt(shift / 2, cp), |key, idx, key_len, _| key[idx % key_len], ) .as_slice(), ) .unwrap(); } }