use crate::utils::{from_bytes, powmod}; use crate::window_state::WindowState; use base64; use eframe::egui; pub struct Window { ciphertext: String, key: String, message: Option, error: Option, } impl Default for Window { fn default() -> Self { Self { ciphertext: String::new(), key: String::new(), message: None, error: None, } } } impl Window { fn decrypt(&mut self) { let split = self.key.split(",").collect::>(); if split.len() != 2 { self.message = None; self.error = Some("Неверный формат ключа".to_string()); return; } let d = match split[0].parse::() { Ok(num) => num, Err(_) => { self.message = None; self.error = Some("Не удалось прочитать открытую экспоненту".to_string()); return; } }; let n = match split[1].parse::() { Ok(num) => num, Err(_) => { self.message = None; self.error = Some("Не удалось прочитать модуль".to_string()); return; } }; let cipher = match base64::decode(&self.ciphertext) { Ok(v) => v, Err(_) => { self.message = None; self.error = Some("Введён некорректный шифротекст".to_string()); return; } }; if cipher.len() == 0 || cipher.len() % 4 != 0 { self.message = None; self.error = Some("Введён некорректный шифротекст".to_string()); return; } let mut nums = Vec::new(); for i in 0..cipher.len() / 4 { let num = from_bytes( cipher[4 * i], cipher[4 * i + 1], cipher[4 * i + 2], cipher[4 * i + 3], ); nums.push(powmod(num, d, n) as u8); } let message = match String::from_utf8(nums) { Ok(m) => m, Err(_) => { self.message = None; self.error = Some("Расшифрованное сообщение не является UTF-8".to_string()); return; } }; self.message = Some(message); } } 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.ciphertext)); ui.label("Закрытый ключ:"); let resp2 = ui.add(egui::TextEdit::singleline(&mut self.key)); if resp1.changed() || resp2.changed() { self.message = None; self.error = None; } if ui.button("Расшифровать").clicked() { self.decrypt(); } if let Some(text) = &self.message { let mut tmp = text.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); } } }