예제 #1
0
        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);
        }
예제 #2
0
        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));
        }
예제 #3
0
        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();
        }
예제 #4
0
        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];
            }
        }
예제 #5
0
        //Метод, генерирующий неприводимые полиномы нужной степени
        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);
        }
예제 #6
0
        //Обыкновенное сложение (не по модулю 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));
        }
예제 #7
0
        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' не дал треубемого остатка от деления. Следовательно, " +
                                 "в полученном слове невозможно исправить ошибки.";
            }
        }