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.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_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 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 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); }
//Обыкновенное сложение (не по модулю 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 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' не дал треубемого остатка от деления. Следовательно, " + "в полученном слове невозможно исправить ошибки."; } }