diff options
| author | Andrew Guschin <guschin.drew@gmail.com> | 2022-09-19 18:59:44 +0400 |
|---|---|---|
| committer | Andrew Guschin <guschin.drew@gmail.com> | 2022-09-19 18:59:44 +0400 |
| commit | 5540868947ce5380f44188a01165d329a8d38cf7 (patch) | |
| tree | caba459d2ec469d4493603a1512044a4659a5fee | |
| parent | 313b245ba9bd4ac70c76383f0ec80a31a6cc1fa3 (diff) | |
Более идиоматичная реализация первой лабораторной
| -rw-r--r-- | src/main.rs | 162 |
1 files changed, 75 insertions, 87 deletions
diff --git a/src/main.rs b/src/main.rs index d6d7708..b2a8661 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,47 +5,48 @@ fn main() { eframe::run_native( "Криптографические методы защиты информации", options, - Box::new(|_cc| Box::new(MyApp::default())), + Box::new(|_cc| Box::new(Application::default())), ); } -struct MyApp { +enum State { + Idle, + Running(u32), + Done, + Error, +} + +struct Application { order: u32, - lastorder: u32, - check: u32, - elements: Vec<u32>, - computing: bool, - computed: bool, - current: u32, - error: bool, - element_checked: bool, - element_true: bool, + element: u32, + element_check: Option<bool>, + primitive_roots: Vec<u32>, + state: State, } -impl Default for MyApp { +impl Default for Application { fn default() -> Self { Self { order: 29, - lastorder: 0, - check: 2, - elements: Vec::new(), - computing: false, - computed: true, - current: 1, - error: false, - - element_checked: false, - element_true: false, + element: 2, + element_check: None, + primitive_roots: Vec::new(), + state: State::Idle, } } } -fn modpow(x: u32, e: u32, m: u32) -> u32 { +fn min_order(x: u32, order: u32) -> u32 { + let mut min = 0; let mut pow = x; - for _ in 1..e { - pow = (pow * x) % m; + for power in 1..order { + if pow == 1 { + min = power; + break; + } + pow = (pow * x) % order; } - return pow; + return min; } fn is_prime(x: u32) -> bool { @@ -60,90 +61,77 @@ fn is_prime(x: u32) -> bool { return true; } -impl eframe::App for MyApp { +impl eframe::App for Application { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - if self.lastorder != self.order { - self.lastorder = 0; - self.computing = false; - self.computed = false; - self.error = false; - self.element_true = false; - self.element_checked = false; - } + let clear_state = |app: &mut Application| { + app.element_check = None; + app.state = State::Idle; + }; egui::Window::new("Задача №1").show(ctx, |ui| { ui.horizontal(|ui| { ui.label("Порядок поля: "); - ui.add(egui::DragValue::new(&mut self.order).clamp_range(1..=4294967295u32)); + if ui + .add(egui::DragValue::new(&mut self.order).clamp_range(2..=u32::MAX)) + .changed() + { + clear_state(self); + } }); ui.horizontal(|ui| { ui.label("Проверяемый элемент: "); - ui.add(egui::DragValue::new(&mut self.check).clamp_range(1..=self.order - 1)); + if ui + .add(egui::DragValue::new(&mut self.element).clamp_range(1..=self.order - 1)) + .changed() + { + clear_state(self); + } }); + if ui.button("Проверить элемент").clicked() { - let mut min = 0; - for power in 1..self.order { - let pow = modpow(self.check, power, self.order); - if pow == 1 { - min = power; - break; - } - } - if min == self.order - 1 { - self.element_true = true; - } - else { - self.element_true = false; - } - self.lastorder = self.order; - self.element_checked = true; + let min = min_order(self.element, self.order); + self.element_check = Some(min == self.order - 1); } - if self.element_checked { - if self.element_true { + match self.element_check { + Some(true) => { ui.label("Элемент является порождающим элементом"); } - else { + Some(false) => { ui.label("Элемент не является порождающим элементом"); } + None => {} } + if ui.button("Рассчитать порождающие элементы").clicked() { - self.elements.clear(); - if is_prime(self.order) { - self.computing = true; - self.current = 1; + self.primitive_roots.clear(); + self.state = if is_prime(self.order) { + State::Running(1) + } else { + State::Error } - else { - self.error = true; - } - self.lastorder = self.order; } - if self.computing { - ui.label("Вычисление..."); - let mut min = 0; - for power in 1..self.order { - let pow = modpow(self.current, power, self.order); - if pow == 1 { - min = power; - break; + match self.state { + State::Running(current) => { + ui.label("Вычисление..."); + let min = min_order(current, self.order); + if min == self.order - 1 { + self.primitive_roots.push(current); + } + self.state = if current == self.order - 1 { + State::Done + } else { + State::Running(current + 1) } } - if min == self.order - 1 { - self.elements.push(self.current); - } - if self.current == self.order - 1 { - self.computing = false; - self.computed = true; - } - else { - self.current += 1; + State::Done => { + ui.label(format!( + "Порождающие элементы поля F_{}: {:?}", + self.order, self.primitive_roots + )); } - } - else if self.computed && self.lastorder == self.order { - if self.error { + State::Idle => {} + State::Error => { ui.label("Можно указать только простое число!"); } - else { - ui.label(format!("Порождающие элементы поля F_{}: {:?}", self.order, self.elements)); - } } }); } |