use crate::utils::{powmod, to_bytes}; use crate::window_state::WindowState; use base64; use eframe::egui; pub struct Window { message: String, key: String, encrypted: Option, error: Option, } impl Default for Window { fn default() -> Self { Self { message: String::new(), key: String::new(), encrypted: None, error: None, } } } impl Window { fn encrypt(&mut self) { let split = self.key.split(",").collect::>(); if split.len() != 2 { self.encrypted = None; self.error = Some("Неверный формат ключа".to_string()); return; } let e = match split[0].parse::() { Ok(num) => num, Err(_) => { self.encrypted = None; self.error = Some("Не удалось прочитать открытую экспоненту".to_string()); return; } }; let n = match split[1].parse::() { Ok(num) => num, Err(_) => { self.encrypted = None; self.error = Some("Не удалось прочитать модуль".to_string()); return; } }; let mut cipher = Vec::new(); for byte in self.message.clone().into_bytes() { let encr = powmod(byte as u64, e, n); let bytes = to_bytes(encr); cipher.push(bytes.0); cipher.push(bytes.1); cipher.push(bytes.2); cipher.push(bytes.3); } self.encrypted = Some(base64::encode(cipher)); } } impl WindowState for Window { fn get_name(&self) -> &str { "Шифрование сообщения" } fn update(&mut self, ui: &mut egui::Ui) { ui.label("Сообщение для зашифрования:"); let resp1 = ui.add(egui::TextEdit::multiline(&mut self.message)); ui.label("Открытый ключ:"); let resp2 = ui.add(egui::TextEdit::singleline(&mut self.key)); if resp1.changed() || resp2.changed() { self.encrypted = None; self.error = None; } if ui.button("Зашифровать").clicked() { self.encrypt(); } if let Some(cipertext) = &self.encrypted { let mut tmp = cipertext.clone(); ui.label("Зашифрованное сообщение:"); ui.add_enabled(false, egui::TextEdit::multiline(&mut tmp)); if ui.button("Скопировать шифротекст").clicked() { ui.output().copied_text = tmp.clone(); } } if let Some(error) = &self.error { ui.label(error); } } }