diff options
| author | Andrew Guschin <guschin.drew@gmail.com> | 2022-11-13 11:40:34 +0400 |
|---|---|---|
| committer | Andrew Guschin <guschin.drew@gmail.com> | 2022-11-13 11:40:34 +0400 |
| commit | 9bbc7b8c31458fbf8c639794531e3d324004d8d5 (patch) | |
| tree | 7d6128c58518c78da03652e9f4e974e6de5a927f /src | |
| parent | 14fefa99fae1433de08812558c07a0f81c40ab04 (diff) | |
Реализации лабораторных перенесены во отдельную папку
Diffstat (limited to 'src')
| -rw-r--r-- | src/lab1.rs | 134 | ||||
| -rw-r--r-- | src/lab3.rs | 128 | ||||
| -rw-r--r-- | src/lab6.rs | 114 | ||||
| -rw-r--r-- | src/lab7.rs | 305 | ||||
| -rw-r--r-- | src/lab_trait.rs | 6 | ||||
| -rw-r--r-- | src/main.rs | 42 |
6 files changed, 0 insertions, 729 deletions
diff --git a/src/lab1.rs b/src/lab1.rs deleted file mode 100644 index b442199..0000000 --- a/src/lab1.rs +++ /dev/null @@ -1,134 +0,0 @@ -use crate::lab_trait::Lab; -use eframe::egui; - -pub struct Window { - order: u32, - element: u32, - element_check: Option<bool>, - primitive_roots: Vec<u32>, - state: State, -} - -impl Window { - fn clear_state(&mut self) { - self.element_check = None; - self.state = State::Idle; - } -} - -impl Default for Window { - fn default() -> Self { - Self { - order: 29, - element: 2, - element_check: None, - primitive_roots: Vec::new(), - state: State::Idle, - } - } -} - -impl Lab for Window { - fn get_name(&self) -> &str { "Задача №1" } - - fn update(&mut self, ui: &mut egui::Ui) { - ui.horizontal(|ui| { - ui.label("Порядок поля: "); - if ui - .add(egui::DragValue::new(&mut self.order).clamp_range(2..=u32::MAX)) - .changed() - { - self.clear_state(); - } - }); - ui.horizontal(|ui| { - ui.label("Проверяемый элемент: "); - if ui - .add(egui::DragValue::new(&mut self.element).clamp_range(1..=self.order - 1)) - .changed() - { - self.clear_state(); - } - }); - - if ui.button("Проверить элемент").clicked() { - let min = min_order(self.element, self.order); - self.element_check = Some(min == self.order - 1); - } - match self.element_check { - Some(true) => { - ui.label("Элемент является порождающим элементом"); - } - Some(false) => { - ui.label("Элемент не является порождающим элементом"); - } - None => {} - } - - if ui.button("Рассчитать порождающие элементы").clicked() { - self.primitive_roots.clear(); - self.state = if is_prime(self.order) { - State::Running(1) - } else { - State::Error - } - } - 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) - } - } - State::Done => { - ui.label(format!( - "Порождающие элементы поля F_{}: {:?}", - self.order, self.primitive_roots - )); - } - State::Idle => {} - State::Error => { - ui.label("Можно указать только простое число!"); - } - } - } -} - -enum State { - Idle, - Running(u32), - Done, - Error, -} - -fn min_order(x: u32, order: u32) -> u32 { - let mut min = 0; - let mut pow = x; - for power in 1..order { - if pow == 1 { - min = power; - break; - } - pow = (pow * x) % order; - } - return min; -} - -fn is_prime(x: u32) -> bool { - if x <= 1 { - return false; - } - for i in 2..x / 2 + 1 { - if x % i == 0 { - return false; - } - } - return true; -} - diff --git a/src/lab3.rs b/src/lab3.rs deleted file mode 100644 index 7f8edf5..0000000 --- a/src/lab3.rs +++ /dev/null @@ -1,128 +0,0 @@ -use crate::lab_trait::Lab; -use eframe::egui; -use rug::{Complete, Integer}; - -enum State { - Clean, - Done, - Error, -} - -pub struct Window { - str_num: String, - factors: Vec<Integer>, - state: State, -} - -impl Default for Window { - fn default() -> Self { - Self { - str_num: String::from("21894583143407671"), - factors: Vec::new(), - state: State::Clean, - } - } -} - -impl Lab for Window { - fn get_name(&self) -> &str { "Задача №3" } - - fn update(&mut self, ui: &mut egui::Ui) { - ui.horizontal(|ui| { - ui.label("Число: "); - let field = ui.add(egui::TextEdit::singleline(&mut self.str_num)); - if field.changed() { - self.state = State::Clean; - self.factors.clear(); - } - }); - if ui.button("Разложить на множители").clicked() { - self.factors.clear(); - match Integer::parse(&self.str_num) { - Ok(number) => { - self.factors.append(&mut factorize(&number.complete())); - self.state = State::Done; - }, - Err(_) => self.state = State::Error, - }; - } - if let State::Done = self.state { - if self.factors.len() == 1 { - ui.label(format!("Число является простым")); - } - else { - ui.label(format!("Множители: {:?}", self.factors)); - } - } - if let State::Error = self.state { - ui.label("В числе имеются недопустимые символы"); - } - } -} - -fn factorize(n: &Integer) -> Vec<Integer> { - let mut factors = Vec::new(); - let mut front = vec![n.clone()]; - - while !front.is_empty() { - let num = front.pop().unwrap(); - match lehman(&num) { - Some(factor) => { - let other = num.div_exact_ref(&factor).complete(); - front.push(factor); - front.push(other); - }, - None => factors.push(num) - }; - } - - return factors; -} - -fn lehman(n: &Integer) -> Option<Integer> { - let one = &Integer::from(1u32); - let mut a = Integer::from(2u32); - let root3 = n.root_ref(3).complete(); - - while a <= root3 { - let (_, r) = n.div_rem_ref(&a).complete(); - if r == 0 { - return Some(a); - } - a += one; - } - - let root6 = n.root_ref(6).complete(); - let mut k = Integer::from(1u32); - while k <= root3 { - let mut d = Integer::ZERO; - let sqrtk4 = k.sqrt_ref().complete() * 4; - let (r6sk4, _) = root6.div_rem_ref(&sqrtk4).complete(); - while d <= (&r6sk4 + one).complete() { - let kn4: Integer = k.clone() * n.clone() * 4; - let sqrt_kn4 = kn4.sqrt_ref().complete(); - - let number = (sqrt_kn4.clone() + d.clone()).square() - kn4.clone(); - if number.is_perfect_square() { - let big_a = sqrt_kn4 + d.clone(); - let big_b = (big_a.square_ref() - kn4).sqrt(); - - let gcd1 = (big_a.clone() + big_b.clone()).gcd_ref(n).complete(); - let gcd2 = (big_a.clone() - big_b.clone()).gcd_ref(n).complete(); - - if &gcd1 > one && &gcd1 < n { - return Some(gcd1); - } - else if &gcd2 > one && &gcd2 < n { - return Some(gcd2); - } - } - - d += one; - } - k += one; - } - - return None; -} - diff --git a/src/lab6.rs b/src/lab6.rs deleted file mode 100644 index 9061da7..0000000 --- a/src/lab6.rs +++ /dev/null @@ -1,114 +0,0 @@ -use crate::lab_trait::Lab; -use eframe::egui; -use std::collections::HashSet; -use std::collections::HashMap; - -enum State<'a> { - Clean, - Done1, - Done2, - Error(&'a str), -} - -pub struct Window<'a> { - n: u32, - q: u32, - subgroup: Vec<u32>, - subgroups: HashMap<u32, Vec<u32>>, - state: State<'a>, -} - -impl<'a> Default for Window<'a> { - fn default() -> Self { - Self { - n: 6, - q: 3, - subgroup: Vec::new(), - subgroups: HashMap::new(), - state: State::Clean, - } - } -} - -impl<'a> Lab for Window<'a> { - fn get_name(&self) -> &str { "Задача №6" } - - fn update(&mut self, ui: &mut egui::Ui) { - ui.horizontal(|ui| { - ui.label("Порядок группы Z_n: "); - if ui.add(egui::DragValue::new(&mut self.n).clamp_range(2..=u32::MAX)).changed() { - self.state = State::Clean; - self.subgroup.clear(); - } - }); - ui.horizontal(|ui| { - ui.label("Порядок q подгруппы: "); - if ui.add(egui::DragValue::new(&mut self.q).clamp_range(1..=self.n)).changed() { - self.state = State::Clean; - self.subgroup.clear(); - } - }); - if ui.button("Вычислить подгруппу").clicked() { - self.subgroups.clear(); - if self.n % self.q != 0 { - self.state = State::Error("q не является делителем n"); - } - else { - self.subgroups = calculate_subgroups(self.n); - for (_, sg) in &self.subgroups { - if sg.len() == self.q as usize { - self.subgroup = sg.clone(); - break; - } - } - self.state = State::Done1; - } - } - if ui.button("Вычислить все подгруппы").clicked() { - self.subgroups.clear(); - if self.n % self.q != 0 { - self.state = State::Error("q не является делителем n"); - } - else { - self.subgroups = calculate_subgroups(self.n); - self.state = State::Done2; - } - } - match self.state { - State::Clean => {}, - State::Done1 => { - ui.label(format!("Вычисленная подгруппа: {:?}", self.subgroup)); - }, - State::Done2 => { - for (gen, set) in self.subgroups.iter() { - ui.label(format!("Подгруппа {:?} с генератором {}", set, gen)); - } - }, - State::Error(msg) => { ui.label(msg); }, - } - } -} - -fn powmod(x: u32, n: u32, m: u32) -> u32 { - let mut res = 0; - for _ in 0..n { - res = (res + x) % m; - } - return res; -} - -fn calculate_subgroups(n: u32) -> HashMap<u32, Vec<u32>> { - let mut subgroups = HashMap::new(); - for i in 0..n { - let mut group = HashSet::new(); - group.insert(i); - for p in 2..=n { - let power = powmod(i, p, n); - group.insert(power); - } - let mut vec = group.drain().collect::<Vec<u32>>(); - vec.sort(); - subgroups.insert(i as u32, vec); - } - return subgroups; -} diff --git a/src/lab7.rs b/src/lab7.rs deleted file mode 100644 index 030c0d4..0000000 --- a/src/lab7.rs +++ /dev/null @@ -1,305 +0,0 @@ -use crate::lab_trait::Lab; -use eframe::egui; -use std::collections::HashSet; - -enum State { - Nothing, - Cipher, - Decipher, - Line(u32), - - RDecipher, - RLine(u32), -} - -pub struct Window { - state: State, - line: u32, - q1: Vec<String>, - q2: Vec<String>, - q3: Vec<String>, - q4: Vec<String>, - - rq1: String, - rq2: String, - rq3: String, - rq4: String, - rline: u32, -} - -impl Default for Window { - fn default() -> Self { - Self { - state: State::Nothing, - line: 1, - q1: vec![ - "Нечаянно пригрѣтый славой".to_string(), - "Орла двуглаваго щипали".to_string(), - "Остервененіе народа".to_string(), - "Мы очутилися въ П".to_string(), - "Скажи за чѣмъ ты въ сам дѣлѣ".to_string(), - "Но стихоплетъ Великородный".to_string(), - "Авось по манью — --".to_string(), - "Сей всадникъ Папою вѣнчанный".to_string(), - "Безрукій К. друзьямъ Мореи".to_string(), - "А про тебя и въ усъ не дуетъ".to_string(), - "Предавшихъ нѣкогда — --".to_string(), - "Но искры пламени инова".to_string(), - "Они за рюмкой руской водки".to_string(), - "У безпокойнаго Никиты".to_string(), - "Свои рѣшительныя мѣры".to_string(), - "Блеститъ надъ К. тѣнистой".to_string(), - "Надъ нами З — валъ тогда".to_string(), - "У Б — шатра".to_string(), - "Б., зима иль Р. Б.".to_string(), - "А Р. З. главой З.".to_string(), - "Меня уже предупредилъ".to_string(), - "Семействамъ возвратитъ с".to_string(), - "Изчезнувшій какъ тѣнь зари".to_string(), - "Изъ К. ужъ мигалъ".to_string(), - "Ты А. холопъ".to_string(), - "Свирѣпой шайкѣ палачей".to_string(), - "Уже издавно можетъ быть ".to_string(), - ], - q2: vec![ - "Моря достались Албіону".to_string(), - "Авось дороги намъ испр.".to_string(), - "Измученъ казнію покоя".to_string(), - "Кинжалъ… тѣмъ… ".to_string(), - ], - q3: vec![ - "Вл. слабый и лукавый".to_string(), - "Его мы очень смирн знали".to_string(), - "Гроза 12 года".to_string(), - "Но Богъ помогъ — сталъ ропотъ ниже".to_string(), - "И чѣмъ жирнѣе тѣмъ тяжелѣ".to_string(), - "Авось, о Шиболетъ народный".to_string(), - "Авось аренды забывая".to_string(), - "Сей мужъ судьбы, сей странникъ бранный".to_string(), - "Тряслися грозно Пиринеи —".to_string(), - "Я всѣхъ уйму съ моимъ народомъ".to_string(), - "Потѣшный полкъ Петра титана ".to_string(), - "Р. Р. снова присм…".to_string(), - "У нихъ [свои бывали] сходки".to_string(), - "Витійствомъ рѣзкимъ знамениты".to_string(), - "Другъ Марса, Вакха и Венеры".to_string(), - "[Но т] Такъ было надъ Невою льдистой".to_string(), - "Плѣшивый щеголь врагъ труда".to_string(), - "Когда ненаши повара".to_string(), - "Насти… — кто тутъ намъ помогъ?".to_string(), - "И скоро сило вещей".to_string(), - "ОР… нашъ н".to_string(), - "Тебѣ бъ я оду посвятилъ".to_string(), - "Ханжа запрется въ монастырь".to_string(), - "Предъ кѣмъ унизились З".to_string(), - "Волканъ Неаполя пылалъ".to_string(), - ], - q4: vec![ - "Нашъ З. въ покоѣ говорилъ".to_string(), - "Дружина старыхъ усачей".to_string(), - "И пуще З. пошелъ кутить".to_string(), - "Они за чашею вина".to_string(), - "Сбирались члены сей семьи".to_string(), - "Тутъ [бы] Л. дерзко предлагалъ".to_string(), - "Но тамъ гдѣ ранѣе весна ".to_string(), - ], - - rq1: String::new(), - rq2: String::new(), - rq3: String::new(), - rq4: String::new(), - rline: 1, - } - } -} - -impl Lab for Window { - fn get_name(&self) -> &str { - "Задача №7" - } - - fn update(&mut self, ui: &mut egui::Ui) { - if ui.button("Вывести оригинал").clicked() { - self.state = State::Cipher; - } - if ui.button("Вывести дешифровку").clicked() { - self.state = State::Decipher; - } - ui.horizontal(|ui| { - if ui - .add(egui::DragValue::new(&mut self.line).clamp_range(1..=56)) - .changed() - { - self.state = State::Nothing; - } - if ui.button("Вывести строку").clicked() { - self.state = State::Line(self.line); - } - }); - let response = ui.add(egui::TextEdit::multiline(&mut self.rq1)); - if response.changed() { - self.state = State::Nothing; - } - let response = ui.add(egui::TextEdit::multiline(&mut self.rq2)); - if response.changed() { - self.state = State::Nothing; - } - let response = ui.add(egui::TextEdit::multiline(&mut self.rq3)); - if response.changed() { - self.state = State::Nothing; - } - let response = ui.add(egui::TextEdit::multiline(&mut self.rq4)); - if response.changed() { - self.state = State::Nothing; - } - if ui.button("Вывести дешифровку введённого текста").clicked() - { - self.state = State::RDecipher; - } - ui.horizontal(|ui| { - let q1 = self.rq1.lines().collect::<Vec<_>>().len(); - let q2 = self.rq2.lines().collect::<Vec<_>>().len(); - let q3 = self.rq3.lines().collect::<Vec<_>>().len(); - let q4 = self.rq4.lines().collect::<Vec<_>>().len(); - if ui - .add(egui::DragValue::new(&mut self.rline).clamp_range(1..=q1 + q2 + q3 + q4)) - .changed() - { - self.state = State::Nothing; - } - if ui.button("Вывести строку введённого текста").clicked() - { - self.state = State::RLine(self.rline); - } - }); - - match self.state { - State::Nothing => {} - State::Cipher => { - let mut cipher = Vec::new(); - cipher.extend(&self.q1); - cipher.extend(&self.q2); - cipher.extend(&self.q3); - cipher.extend(&self.q4); - egui::ScrollArea::vertical().show(ui, |ui| { - for line in cipher { - ui.label(line); - } - }); - } - State::Decipher => { - egui::ScrollArea::vertical().show(ui, |ui| { - get_poem(&self.q1, &self.q2, &self.q3, &self.q4) - .into_iter() - .for_each(|x| { - ui.label(x); - }); - }); - } - State::Line(n) => { - let poem = get_poem(&self.q1, &self.q2, &self.q3, &self.q4); - ui.label(format!("Строка {}: \"{}\"", n, poem[n as usize - 1])); - } - State::RDecipher => { - let q1 = splitlines(&self.rq1); - let q2 = splitlines(&self.rq2); - let q3 = splitlines(&self.rq3); - let q4 = splitlines(&self.rq4); - let mut lens = HashSet::new(); - lens.insert(q1.len()); - lens.insert(q2.len()); - lens.insert(q3.len()); - lens.insert(q4.len()); - if lens.len() != 1 { - ui.label("Введённые тексты должны быть одинаковой длины"); - } else { - get_random_poem(&q1, &q2, &q3, &q4) - .into_iter() - .for_each(|x| { - ui.label(x); - }); - } - } - State::RLine(n) => { - let q1 = splitlines(&self.rq1); - let q2 = splitlines(&self.rq2); - let q3 = splitlines(&self.rq3); - let q4 = splitlines(&self.rq4); - let mut lens = HashSet::new(); - lens.insert(q1.len()); - lens.insert(q2.len()); - lens.insert(q3.len()); - lens.insert(q4.len()); - if lens.len() != 1 { - ui.label("Введённые тексты должны быть одинаковой длины"); - } else { - let poem = get_random_poem(&q1, &q2, &q3, &q4); - ui.label(format!("Строка {}: \"{}\"", n, poem[n as usize - 1])); - } - } - } - } -} - -fn splitlines(text: &String) -> Vec<String> { - text.lines().map(|x| x.to_string()).collect::<Vec<String>>() -} - -fn get_poem( - q1: &Vec<String>, - _q2: &Vec<String>, - q3: &Vec<String>, - q4: &Vec<String>, -) -> Vec<String> { - let mut cipher = Vec::new(); - cipher.extend(q1); - cipher.extend(q3); - cipher.extend(q4); - let mut key = vec![27, 43, 0, 16]; - let mut poem = Vec::new(); - let mut count = 1; - while key[1] < cipher.len() { - if count == 5 { - for i in 0..=2 { - poem.push(cipher[key[i]].clone()); - key[i] += 1; - } - } else if count == 10 { - for i in 0..=1 { - poem.push(cipher[key[i]].clone()); - key[i] += 1; - } - key[2] += 1; - key[3] += 1; - } else if count == 11 || count >= 13 && count <= 16 { - for i in 0..=2 { - poem.push(cipher[key[i]].clone()); - key[i] += 1; - } - key[3] += 1; - } else { - for i in 0..=3 { - poem.push(cipher[key[i]].clone()); - key[i] += 1; - } - } - count += 1; - } - return poem; -} - -fn get_random_poem( - q1: &Vec<String>, - q2: &Vec<String>, - q3: &Vec<String>, - q4: &Vec<String>, -) -> Vec<String> { - let mut poem = Vec::new(); - for i in 0..q1.len() { - poem.push(q3[i].clone()); - poem.push(q4[i].clone()); - poem.push(q1[i].clone()); - poem.push(q2[i].clone()); - } - return poem; -} diff --git a/src/lab_trait.rs b/src/lab_trait.rs deleted file mode 100644 index 23f110b..0000000 --- a/src/lab_trait.rs +++ /dev/null @@ -1,6 +0,0 @@ -use eframe::egui; - -pub trait Lab { - fn get_name(&self) -> &str; - fn update(&mut self, ui: &mut egui::Ui); -} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index f672971..0000000 --- a/src/main.rs +++ /dev/null @@ -1,42 +0,0 @@ -mod lab1; -mod lab3; -mod lab6; -mod lab7; -mod lab_trait; - -use eframe::egui; -use lab_trait::Lab; - -fn main() { - let options = eframe::NativeOptions::default(); - eframe::run_native( - "Криптографические методы защиты информации", - options, - Box::new(|_cc| Box::new(Application::default())), - ); -} - -struct Application { - labs: Vec<Box<dyn Lab>>, -} - -impl Default for Application { - fn default() -> Self { - Self { - labs: vec![ - Box::new(lab1::Window::default()), - Box::new(lab3::Window::default()), - Box::new(lab6::Window::default()), - Box::new(lab7::Window::default()), - ], - } - } -} - -impl eframe::App for Application { - fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - for window in &mut self.labs { - egui::Window::new(window.get_name()).show(ctx, |ui| window.update(ui)); - } - } -} |