summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Guschin <guschin.drew@gmail.com>2022-09-19 18:59:44 +0400
committerAndrew Guschin <guschin.drew@gmail.com>2022-09-19 18:59:44 +0400
commit5540868947ce5380f44188a01165d329a8d38cf7 (patch)
treecaba459d2ec469d4493603a1512044a4659a5fee
parent313b245ba9bd4ac70c76383f0ec80a31a6cc1fa3 (diff)
Более идиоматичная реализация первой лабораторной
-rw-r--r--src/main.rs162
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));
- }
}
});
}