public static BinaryString operator %(BinaryString bin_str1, BinaryString bin_str2) { if (bin_str1.cutUnsignificantZeros().size() < bin_str2.cutUnsignificantZeros().size()) { return(bin_str1); } BinaryString dividend = bin_str1.cutUnsignificantZeros(); //Делимое BinaryString divider = bin_str2.cutUnsignificantZeros(); //Делитель while (dividend.size() >= divider.size()) { //Выделяем часть делимого, равную по размеру делителю string temp_str = dividend.ToString().Substring(0, divider.size()); //То, что останется после сложения делителя и части делимого в виде строки string new_dividend = (new BinaryString(temp_str) + divider).cutUnsignificantZeros().ToString(); if (dividend.size() > divider.size()) //Присоединяем оставшийся кусок делимого { new_dividend += dividend.ToString().Substring(divider.size(), dividend.size() - divider.size()); } dividend = new BinaryString(new_dividend); dividend = dividend.cutUnsignificantZeros(); } if (dividend.size() == 0) { dividend = new BinaryString("0"); } return(dividend); }
public static BinaryString operator *(BinaryString bin_str1, BinaryString bin_str2) { if (bin_str1.weight() == 0 || bin_str2.weight() == 0) //Проверка умножения на ноль { int size = (bin_str1.size() < bin_str2.size()) ? bin_str1.size() : bin_str2.size(); string result_str = ""; for (int i = 0; i < size; ++i) { result_str += "0"; } return(new BinaryString(result_str)); } string[] temp_arr = new string[bin_str2.weight()]; string str_of_zeros = ""; int cur_index = 0; for (int i = bin_str2.size() - 1; i >= 0; --i) { if (bin_str2[i] == '1') { temp_arr[cur_index++] = bin_str1.ToString() + str_of_zeros; } str_of_zeros += "0"; } BinaryString result = new BinaryString(temp_arr[0]); for (int i = 1; i < temp_arr.Length; ++i) { result += new BinaryString(temp_arr[i]); } return(result); }
public GF2(int degree, BinaryString polynomial) { polynomial = polynomial.cutUnsignificantZeros(); //Проверка на соответствие degree степени полинома polinomial if (degree != polynomial.size() - 1) { MessageBox.Show("Степень образующего многочлена не соответствует степени поля Галуа."); Application.Exit(); } degree_ = degree; elements_ = new BinaryString[(int)Math.Pow(2, degree_)]; polynomial_ = polynomial; //Формируем нулевой элемент string temp_str = ""; for (int i = 0; i < degree_; ++i) { temp_str += "0"; } elements_[0] = new BinaryString(temp_str); //Формируем ненулевые элементы поля for (int i = 1; i < elements_.Length; ++i) { elements_[i] = elements_[i - 1]; ++elements_[i]; } }
public Form4(Form3 previous_form, BinaryString polynomial, int n, int k, int d) { InitializeComponent(); d_ = d; previous_form_ = previous_form; coding_form_ = new CodingForm(polynomial, n, k, this); decoding_form_ = new DecodingForm(polynomial, n, k, this); }
private void Form3_Load(object sender, EventArgs e) { //Находим первый примитивный элемент BinaryString first_primitive = new BinaryString(); for (int i = 2; i < Math.Pow(2, galois_field_.polynomial.size() - 1); ++i) { if (galois_field_.isPrimitive(galois_field_.element(i))) { first_primitive = galois_field_.element(i); break; } } //Возводим примитивный элемент во все взаимно простые с 2^m - 1 степени int field_size = (int)Math.Pow(2, galois_field_.polynomial.degree); if (isPrime(field_size - 1)) //Если 2^m - 1 - простое число { //все элементы поля, кроме 0 и 1 - примитивные for (int i = 2; i < Math.Pow(2, galois_field_.degree); ++i) { primitive_elems_.Add(galois_field_.element(i)); } } else { for (int i = 1; i < field_size - 1; ++i) { if (i > 500) { break; //Ограничиваем количество примитивных элементов } if (gcd(i, field_size - 1) == 1) { primitive_elems_.Add(galois_field_.Pow(first_primitive, i)); } } } //Создаем кнопки for (int i = 0; i < primitive_elems_.Count; ++i) { RadioButton new_button = new RadioButton(); new_button.Text = primitive_elems_.ElementAt(i).transformToPolynomial(); new_button.AutoSize = true; radio_button_.Add(new_button); } radio_button_.ElementAt(0).Location = new System.Drawing.Point(50, 10); radio_button_.ElementAt(0).Size = radio_button_.ElementAt(0).PreferredSize; panel.Controls.Add(radio_button_.ElementAt(0)); for (int i = 1; i < radio_button_.Count; ++i) { radio_button_.ElementAt(i).Location = new System.Drawing.Point(50, radio_button_.ElementAt(i - 1).Location.Y + 30); radio_button_.ElementAt(i).Size = radio_button_.ElementAt(i).PreferredSize; panel.Controls.Add(radio_button_.ElementAt(i)); } }
public Form3(int n, int d, BinaryString polynomial, Form2 prev_form) { InitializeComponent(); //Создаем поле Галуа galois_field_ = new GF2(polynomial.degree, polynomial); n_ = n; d_ = d; prev_form_ = prev_form; radio_button_ = new List <RadioButton>(); primitive_elems_ = new List <BinaryString>(); }
public ResultCodingForm(CodingForm prev_form, BinaryString polynomial, BinaryString inf_word) { InitializeComponent(); previous_form_ = prev_form; text_box.Text += "Закодируем слово " + inf_word.ToString() + ". Для этого умножим его на " + "образующий многочлен " + polynomial.ToString() + ":\nB = I * F = " + inf_word.ToString() + " * " + polynomial.ToString() + " = "; BinaryString code_word = polynomial * inf_word; text_box.Text += code_word.ToString(); }
public CodingForm(BinaryString polynomial, int n, int k, Form4 prev_form) { InitializeComponent(); //Записываем параметры на форму l_polynomial.Text += polynomial.ToString(); l_n.Text += n; l_k.Text += k; //Связываем с предыдущей формой previous_form_ = prev_form; k_ = k; polynomial_ = polynomial; }
private void b_gen_word_Click(object sender, EventArgs e) { Random rand = new Random(); //Очищаем текстБокс tb_code_word.Text = String.Empty; //Генерируем информационное слово string inf_word_str = "1"; for (int i = 1; i < k_; ++i) { inf_word_str += rand.Next(0, 2); } //Умножаем информационное слово на образующий многочлен BinaryString code_word = new BinaryString(inf_word_str) * polynomial_; //Генерируем количество ошибок int num_of_mistakes = rand.Next(1, (d_ - 1) / 2 + 1); //Генерируем первую позиции интервала, в котором будут находиться ошибки int first_pos = 0; if (k_ != 1) { first_pos = rand.Next(1, code_word.size() - polynomial_.size() - 1); } //Допускаем ошибки string code_word_str = code_word.ToString(); for (int i = 0; i < num_of_mistakes; ++i) { int index = rand.Next(first_pos, first_pos + polynomial_.size()); code_word[index] = BinaryString.InverseChar(code_word[index]); } //Проверяем, есть ли ошибки в слове, и если нет, допускаем одну if (code_word.ToString() == code_word_str) { int index = rand.Next(1, code_word.size()); code_word[index] = BinaryString.InverseChar(code_word[index]); } //Записываем в текстБокс tb_code_word.Text += code_word.ToString(); }
public static BinaryString operator /(BinaryString bin_str1, BinaryString bin_str2) { if (bin_str1.cutUnsignificantZeros().size() < bin_str2.cutUnsignificantZeros().size()) { return(new BinaryString("0")); } BinaryString dividend = bin_str1.cutUnsignificantZeros(); //Делимое BinaryString divider = bin_str2.cutUnsignificantZeros(); //Делитель string result_str = string.Empty; while (dividend.size() >= divider.size()) { result_str += "1"; //Кусок делимого, который будем складывать по модулю 2 с делителем //(по принципу деления в столбик) string temp_div = dividend.ToString().Substring(0, divider.size()); BinaryString temp_dividend = new BinaryString(temp_div); //Результат этого сложения BinaryString cur_add_res = (temp_dividend + divider).cutUnsignificantZeros(); //Добавляем нули после текущей единицы, если необходимо int num_of_zeros; if (cur_add_res.size() == divider.size() - 1 && dividend.size() - divider.size() > 0) { num_of_zeros = 0; } else if (dividend.size() - divider.size() < divider.size() - cur_add_res.size()) { num_of_zeros = dividend.size() - divider.size(); } else { num_of_zeros = divider.size() - cur_add_res.size() - 1; } for (int i = 0; i < num_of_zeros; ++i) { result_str += "0"; } dividend = new BinaryString(cur_add_res.ToString() + dividend.ToString().Substring(divider.size())); } return(new BinaryString(result_str)); }
private void b_code_word_Click(object sender, EventArgs e) { //Проверка введенного слова if (tb_inf_word.TextLength != k_) { MessageBox.Show("Длина информационного слова должна равняться " + k_ + ". Вы ввели " + tb_inf_word.TextLength + " символов."); return; } //Считываем информационное слово BinaryString information_word = new BinaryString(tb_inf_word.Text); next_form_ = new ResultCodingForm(this, polynomial_, information_word); next_form_.Show(); this.Hide(); }
//Метод, генерирующий неприводимые полиномы нужной степени public static List <BinaryString> generatePolynomialsOfDegree(int deg) { List <BinaryString> result_list = new List <BinaryString>(); //Генерируем первый полином нужной степени string temp_str = "1"; for (int i = 0; i < deg; ++i) { if (i == deg - 1) { temp_str += '1'; } else { temp_str += '0'; } } BinaryString cur_polynomial = new BinaryString(temp_str); //Проверяем на неприводимость все полиномы степени deg while (cur_polynomial.size() == deg + 1) { //Делим текущий полином на все неприводимые полиномы степеней вплоть до deg/2 BinaryString cur_divider = new BinaryString("10"); while (cur_divider.size() <= (deg + 2) / 2) { if ((cur_polynomial % cur_divider).ToString() == "0") //Если нашли делитель полинома { break; } ++cur_divider; } if (cur_divider.size() > (deg + 2) / 2) { result_list.Add(cur_polynomial); } ++cur_polynomial; } return(result_list); }
public bool isPrimitive(BinaryString element) { if (element.cutUnsignificantZeros().ToString() == "1" || element.cutUnsignificantZeros().ToString() == "0") { return(false); } BinaryString el = element % polynomial_; for (int i = 1; i < (int)Math.Pow(2, degree_) - 1; ++i) { if (el.cutUnsignificantZeros().ToString() == "1") { return(false); } el *= element; el %= polynomial_; } return(true); }
public bool isRootOf(BinaryString root, BinaryString equation) { BinaryString result = new BinaryString("0"); for (int i = 0; i <= equation.degree; ++i) { if (equation[equation.degree - i] == '1') { result += galois_field_.Pow(root, i); } } if (result.cutUnsignificantZeros().ToString() == "0") { return(true); } else { return(false); } }
public BinaryString Pow(BinaryString b_string, int degree) { if (degree < 0) { return(new BinaryString("0")); } if (degree == 0) { return(new BinaryString("1")); } BinaryString result = b_string; for (int i = 1; i < degree; ++i) { result *= b_string; } result %= polynomial_; return(result); }
public ResultDecodingForm(DecodingForm prev_form, BinaryString polynomial, BinaryString code_word) { InitializeComponent(); //Связываем с предыдущей формой previous_form_ = prev_form; text_box.Text += "Пусть B' - полученное кодовое слово (с ошибками или без), \nB - отправленное " + "кодовое слово\nB = B', если B' не " + "содержит ошибок;\nB = B' + e, иначе (e - вектор ошибок)\n\nДекодируем кодовое " + "слово " + code_word.ToString() + ". Для этого разделим его на " + "образующий многочлен " + polynomial.ToString() + ":\nI' = B' / F = " + code_word.ToString() + " / " + polynomial.ToString() + " = "; BinaryString inf_word = code_word / polynomial; text_box.Text += inf_word.ToString() + "\n\nОстаток от деления: e = "; BinaryString remainder = code_word % polynomial; text_box.Text += remainder.ToString(); if (remainder.weight() == 0) { text_box.Text += "\nВес остатка равен 0, следовательно, кодовое слово В не содержит ошибок. Значит, " + "I = I' = " + inf_word.ToString() + " - искомое информационное слово."; return; } if (remainder.weight() <= (prev_form.d - 1) / 2) { text_box.Text += "\n\nКоличество исправляемых ошибок: r = " + (prev_form.d - 1) / 2 + "\n\nВес " + "остатка w(e) = " + remainder.weight() + "\n\nТак как выполняется неравенство w <= r, то мы " + "можем исправить ошибки в полученном кодовом слове и найти информационное слово следующим " + "образом:\nI = (B' + e) / F = (" + code_word.ToString() + " + " + remainder.ToString() + ") / " + polynomial.ToString() + " = "; BinaryString B = code_word + remainder; text_box.Text += B.ToString() + " / " + polynomial.ToString() + " = "; BinaryString I = B / polynomial; text_box.Text += I.ToString(); return; } text_box.Text += "\nВес остатка: w(e) = " + remainder.weight() + ".\n\nКоличество исправляемых ошибок:" + " r =" + (prev_form.d - 1) / 2 + "\n\nТак как w > r (1), то для исправления ошибок в полученном кодовом" + " слове необходимо делать циклические сдвиги B' до тех пор, пока условие (1) не нарушится.\n\nПусть " + "Bi - слово, полученное после i циклических сдвигов вправо слова B', ei - остаток от деления Bi на F." + " Выполним сдвиги: "; BinaryString cur_b = code_word.RightCyclShift(1); int i; for (i = 1; i < code_word.size(); ++i) { text_box.Text += "\n\nB" + i + " = " + cur_b.ToString() + ", e" + i + " = "; BinaryString cur_rem = cur_b % polynomial; text_box.Text += cur_rem.ToString() + ", w(e" + i + ") = " + cur_rem.weight(); if (cur_rem.weight() <= (prev_form.d - 1) / 2) { text_box.Text += "\n\nУсловие (1) нарушилось, следовательно, можно исправить ошибки:\nB'" + i + " = B" + i + " + e" + i + " = " + cur_b.ToString() + " + " + cur_rem.ToString() + " = "; BinaryString res_of_add = cur_b + cur_rem; text_box.Text += res_of_add.ToString() + "\nДля этого необходимо сделать " + i + " циклических " + "сдвигов влево полученного слова: B = "; BinaryString new_b = res_of_add.LeftCyclShift(i); text_box.Text += new_b.ToString() + "\n\nТеперь мы можем получить информационное слово: I = B / F = " + new_b.ToString() + " / " + polynomial.ToString() + " = "; BinaryString I = new_b / polynomial; text_box.Text += I.ToString(); break; } cur_b = cur_b.RightCyclShift(1); } if (i == code_word.size()) { text_box.Text += "\n\nНи один сдвиг слова B' не дал треубемого остатка от деления. Следовательно, " + "в полученном слове невозможно исправить ошибки."; } }
//Обыкновенное сложение (не по модулю 2) private BinaryString add(BinaryString bin_str) { int min_size = (size() < bin_str.size()) ? size() : bin_str.size(); int max_size = (size() > bin_str.size()) ? size() : bin_str.size(); string result_string = ""; byte transp_digit = 0;//Разряд переноса //Складываем строки for (int i = 0; i < min_size; ++i) { if (string_[size() - i - 1] == '0' && bin_str.string_[bin_str.size() - i - 1] == '0') { result_string += transp_digit.ToString(); transp_digit = 0; } else if (string_[size() - i - 1] == '0' && bin_str.string_[bin_str.size() - i - 1] == '1' || string_[size() - i - 1] == '1' && bin_str.string_[bin_str.size() - i - 1] == '0') { if (transp_digit == 0) { result_string += "1"; } else { result_string += "0"; } } else { result_string += transp_digit.ToString(); transp_digit = 1; } } string largest_string = (size() > bin_str.size()) ? string_ : bin_str.string_; for (int i = min_size; i < max_size; ++i) { if (transp_digit == 1) { switch (largest_string[max_size - i - 1]) { case '0': result_string += "1"; transp_digit = 0; break; case '1': result_string += "0"; break; } } else { result_string += largest_string[max_size - i - 1]; } } if (transp_digit == 1) { result_string += "1"; } result_string = new string(result_string.ToCharArray().Reverse().ToArray()); //Переворачиваем результирующую строку return(new BinaryString(result_string)); }
public BCHCode(int n, int m, int d, BinaryString alpha, BinaryString polynomial, Form3 previous_form) { text_ = "Построим код БЧХ для следующих параметров: n = " + n + ", d = " + d; d_ = d; n_ = n; alpha_ = alpha; galois_field_ = new GF2(m, polynomial); previous_form_ = previous_form; int s = (int)(Math.Pow(2, m) - 1) / n; text_ += ", α = " + alpha.transformToPolynomial() + ", P(x) = " + galois_field_.polynomial.transformToPolynomial(); text_ += "\n\nНаходим минимальное число m, такое, что n | 2^m - 1. m = " + m; text_ += "\n\nНаходим s по формуле: s = ((2^m) - 1)/n, s = " + s; //Формируем элементы β, β^2,...,β^(d-1) BinaryString[] beta = new BinaryString[d_ - 1]; beta[0] = galois_field_.Pow(alpha, s); text_ += "\n\nНаходим β по формуле: β = α^s, β = " + beta[0].transformToPolynomial(); text_ += "\nВычисляем β^2,...,β^(d-1): "; for (int i = 1; i < d_ - 1; ++i) { beta[i] = beta[i - 1] * beta[0]; if (i != 1) { text_ += ", "; } text_ += "\nβ^" + (i + 1) + " = (" + beta[0].transformToPolynomial() + ")*(" + beta[i - 1].transformToPolynomial() + ") = " + beta[i].transformToPolynomial(); if (beta[i].ToString() != (beta[i] % galois_field_.polynomial).ToString()) { text_ += " = " + (beta[i] % galois_field_.polynomial).transformToPolynomial(); } beta[i] %= galois_field_.polynomial; } //Разбиваем β, β^2,...,β^(d-1) на цикломатические классы List <List <BinaryString> > cyclomatic_classes = new List <List <BinaryString> >(); cyclomatic_classes.Add(new List <BinaryString>()); cyclomatic_classes.ElementAt(0).Add(beta[0]); for (int i = 1; i < d - 1; ++i) { int j; for (j = 0; j < i; ++j) //Выясняем, входит ли beta[i] в к-л существующий цикл.класс { if (inSameCyclClass(i + 1, j + 1, (int)(Math.Pow(2, m) - 1) / s)) { for (int k = 0; k < cyclomatic_classes.Count; ++k) //Ищем нужный цикл. класс { if (cyclomatic_classes.ElementAt(k).Contains(beta[j])) { cyclomatic_classes.ElementAt(k).Add(beta[i]); } } break; } } if (j == i) //если цикл. класс не найден { //cоздаем новый cyclomatic_classes.Add(new List <BinaryString>()); cyclomatic_classes.ElementAt(cyclomatic_classes.Count - 1).Add(beta[i]); } } text_ += "\n\nРазбиваем элементы β, β^2,...,β^(d-1) на цикломатические классы:"; for (int cycl_class = 0; cycl_class < cyclomatic_classes.Count; ++cycl_class) { text_ += "\n" + (cycl_class + 1) + "-й цикломатический класс: "; for (int elem = 0; elem < cyclomatic_classes.ElementAt(cycl_class).Count; ++elem) { text_ += cyclomatic_classes.ElementAt(cycl_class).ElementAt(elem).transformToPolynomial(); if (elem < cyclomatic_classes.ElementAt(cycl_class).Count - 1) { text_ += ", "; } } } //Ищем минимальные полиномы, которые будем проверять List <BinaryString> polynomials_to_check = new List <BinaryString>(); for (int i = 1; i <= m; ++i) { if (m % i == 0) { List <BinaryString> temp_list = GF2.generatePolynomialsOfDegree(i); polynomials_to_check.AddRange(temp_list); } } text_ += "\n\nРаскладываем полином x^" + (Math.Pow(2, m) - 1) + " + 1 на множители:\n" + "x^" + (Math.Pow(2, m) - 1) + " + 1 = "; for (int i = 0; i < polynomials_to_check.Count; ++i) { text_ += "(" + polynomials_to_check.ElementAt(i).transformToPolynomial() + ")"; if (i < polynomials_to_check.Count - 1) { text_ += "*"; } } //Составляем образующий многочлен text_ += "\n\nСреди делителей полинома x^" + (Math.Pow(2, m) - 1) + " + 1 ищем минимальный для каждого " + "цикломатического класса:"; string main_pol_dividers = ""; code_polynomial_ = new BinaryString("1"); int cur_cycl_class = 0; for (int i = 0; i < polynomials_to_check.Count && cur_cycl_class < cyclomatic_classes.Count; ++i) { if (isRootOf(cyclomatic_classes.ElementAt(cur_cycl_class).ElementAt(0), polynomials_to_check.ElementAt(i))) { text_ += "\n\nДля " + (cur_cycl_class + 1) + "-го цикломатического класса: Р" + (i + 1) + "(x) = " + polynomials_to_check.ElementAt(i).transformToPolynomial(); text_ += "\nP" + (i + 1) + "(" + cyclomatic_classes.ElementAt(cur_cycl_class).ElementAt(0).transformToPolynomial() + ") = "; string temp_str1 = ""; string temp_str2 = " = "; for (int j = 0; j <= polynomials_to_check.ElementAt(i).degree; ++j) { if (polynomials_to_check.ElementAt(i)[j] == '1') { if (temp_str1.Length > 0) { temp_str1 += " + "; temp_str2 += " + "; } if (j == polynomials_to_check.ElementAt(i).degree) { temp_str1 += "1"; temp_str2 += "1"; } else { temp_str1 += "(" + cyclomatic_classes.ElementAt(cur_cycl_class).ElementAt(0).transformToPolynomial() + ")^" + (polynomials_to_check.ElementAt(i).degree - j); temp_str2 += (galois_field_.Pow(cyclomatic_classes.ElementAt(cur_cycl_class).ElementAt(0), polynomials_to_check.ElementAt(i).degree - j) % galois_field_.polynomial).transformToPolynomial(); } } } text_ += temp_str1 + temp_str2 + " = 0"; if (main_pol_dividers.Length > 0) { main_pol_dividers += " * "; } main_pol_dividers += "(" + polynomials_to_check.ElementAt(i).transformToPolynomial() + ")"; code_polynomial_ *= polynomials_to_check.ElementAt(i); cur_cycl_class++; i = -1; } } text_ += "\n\nНаходим образующий многочлен для кода:\n"; if (main_pol_dividers.Contains('*')) { text_ += "F(x) = " + main_pol_dividers + " = " + code_polynomial_.transformToPolynomial() + "\n\n"; } else { text_ += "F(x) = " + code_polynomial_.transformToPolynomial() + "\n\n"; } //Устанавливаем параметр k k = n - code_polynomial_.degree; }