AIT/src/controller/model_utils/hamming_code_seven_four.rs

138 lines
4.5 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use std::collections::HashMap;
use crate::{
controller::view_utils::{hamming_code_input_utils::*, input_utils::*},
model::models::*,
};
/// **Синдромы**
///
/// ошибочная позиция 1 false true true.
///
/// ошибочная позиция 2 false false true.
///
/// ошибочная позиция 3 true false true.
///
/// ошибочная позиция 4 false true false.
///
/// ошибочная позиция 5 true true false.
///
/// ошибочная позиция 6 true false false.
///
/// ошибочная позиция 7 false false false.
pub fn hamming(raw_input: String, mode: HammingMode) -> Result<String, String> {
let length_of_code: usize = mode.clone() as usize;
let prepared_input: String = processing_input(&raw_input);
let (fc, sc): (bool, bool) =
check_correct_binary_code(&raw_input, &prepared_input, length_of_code);
if !fc || !sc {
Err("Ошибка. Проверьте корректность ввода.".to_string())
} else {
let mut data: String = String::new();
let prepared_data: Vec<u8> = from_string_to_vec_bits(prepared_input);
match mode {
HammingMode::Encrypt => hamming_encrypt_data(&prepared_data, &mut data, length_of_code),
HammingMode::Decrypt => hamming_decrypt_data(&prepared_data, &mut data, length_of_code),
}
return Ok(data);
}
}
pub fn hamming_encrypt_data(data: &Vec<u8>, result_string: &mut String, length_of_code: usize) {
let mut i: usize = length_of_code;
while i <= data.len() {
let data_bits: &[u8] = &data[i - length_of_code..i];
let (check_bit_1, check_bit_2, check_bit_3) = (
data_bits[0] ^ data_bits[1] ^ data_bits[3],
data_bits[0] ^ data_bits[2] ^ data_bits[3],
data_bits[1] ^ data_bits[2] ^ data_bits[3],
);
result_string.push_str(&*format!(
"{check_bit_1}{}{check_bit_2}{}{check_bit_3}{}{} ",
data_bits[0], data_bits[1], data_bits[2], data_bits[3]
));
i += length_of_code;
}
}
pub fn hamming_decrypt_data(data: &Vec<u8>, result_string: &mut String, length_of_code: usize) {
let mut general_length: usize = length_of_code;
let syndromes: HashMap<usize, (bool, bool, bool)> = HashMap::from([
(1, (false, true, true)),
(2, (false, false, true)),
(3, (true, false, true)),
(4, (false, true, false)),
(5, (true, true, false)),
(6, (true, false, false)),
(7, (false, false, false)),
]);
let mut errors: String = String::new();
while general_length <= data.len() {
let data_bits = &data[general_length - length_of_code..general_length];
let checked_bits: (bool, bool, bool) = (
(data_bits[1] ^ data_bits[3] ^ data_bits[6]) == data_bits[0],
(data_bits[1] ^ data_bits[5] ^ data_bits[6]) == data_bits[2],
(data_bits[3] ^ data_bits[5] ^ data_bits[6]) == data_bits[4],
);
if let (true, true, true) = checked_bits {
general_length += length_of_code;
continue;
} else {
let error_position: &usize = syndromes
.iter()
.find(move |&(&_error_position, &error)| error == checked_bits)
.unwrap()
.0;
let uncorrect_code: String = from_vec_bits_to_string(&data_bits);
let correct_code: String = from_vec_bits_to_string(
data_bits
.iter()
.enumerate()
.map(|(index, &bit)| {
if index == error_position - 1 {
(bit == 0u8).into()
} else {
bit
}
})
.collect::<Vec<u8>>()
.as_slice(),
);
let error = format!(
"Ошибка в коде {} [{uncorrect_code}], позиция ошибки {}, корректный код: [{correct_code}]; \n",
general_length / 7,
error_position
);
errors.push_str(error.as_str());
general_length += length_of_code;
}
}
if data.len() > 0 {
if errors.len() == 0 {
result_string.push_str("Все коды корректны.");
} else {
result_string.push_str(errors.as_str());
}
} else {
result_string.push_str("Введите код для проверки.")
}
}