Міністерство освіти та науки України
Національний університет “Львівська політехніка”
Алгоритмічна реалізація циклічного кодера та декодера. Створення Windows Forms програм
на основі Microsoft Visual Studio .NET
лабораторна робота № 2
з дисципліни “Основи збору, передачі та оброблення інформації”
Варіант № 15 група 3
Мета роботи: отримати навики по розробленню Windows Forms програм CLR за допомогою інструментарію Visual C++ 2005 та реалізувати циклічний кодер/декодер алгоритмічною мовою С++.
Завдання
Написати мовою С++ програму, що реалізує алгоритм роботи циклічного кодера та декодера для коду БЧХ, згідно варіанту завдання. Вигляд програми має відповідати рис. 5.1.
Функція кодування зчитує число у двійковому вигляді з вікна №1 (G_X () та виводить закодоване повідомлення у двійковому вигляді у вікно №2 (F_X). Параметри коду БЧХ задаються у середині програми. Відповідно до цих параметрів вибрати мінімальний по розміру беззнаковий цілий тип для закодованого повідомлення.
Функція декодування зчитує закодоване повідомлення у двійковому вигляді з вікна №2 (F_X), а з вікна №4 зчитує у двійковому виді маску з “1” у спотворюваних розрядах, за допомогою якої здійснює інверсію розрядів закодованого повідомлення F_X. Результат декодування виводить у вікно №3 (( G_X). Механізм виявлення та виправлення помилок реалізувати за допомогою алгоритму з циклічними зсувами. Усю необхідну додаткову інформацію виводити у широке інформаційне вікно.
На основі розробленої програми провести дослідження можливостей по виявленню та виправленню помилок для заданого твірного поліному БЧХ. Зняти 10 результатів виконання циклічного кодування-декодування при внесенні спотворень згідно таблиці 2.
№ п/п
Параметри циклічного коду БЧХ
15
n = 63; k = 30; s = 6; P(x) = 157464165547
без спотворень; 2) спотворився молодший розряд закодованого повідомлення F_X; 3) спотворився старший розряд; 4) спотворилися два молодших розряди; 5) спотворилися два старших розряди; 6-10 набори спотворень вибираються з таблиці згідно № 13 та № групи 3
6) 0,1,2,3,6,17,48,54; 7) 4,9,20,21,23,46; 8) 3, 26; 9) 14; 10) 4;
Циклічний кодер
Циклічні коди відносяться до числа блокових систематичних кодів, у яких кожна комбінація кодується самостійно (у вигляді блоку) таким чином, що інформаційні k та контрольні m символи (розряди) завжди знаходяться на визначених місцях. Назва кодів походить від їх циклічних властивостей: якщо – кодове слово циклічного коду, тоді , отримане циклічним зсувом елементів C, також є кодовим словом. Усі циклічні зсуви C, утворюють кодові слова. І, як результат циклічної властивості, ці коди володіють значною кількістю структурних зручностей, які можна використати при реалізації операцій кодування та декодування.
Можливість виявлення та виправлення практично будь-яких помилок при відносно малій надлишковості та простій реалізації, зробило ці коди широко розповсюдженими. Циклічні коди використовуються в безпровідній телефонії та у мобільному зв’язку.
Теорія циклічних кодів базується на теорії груп та алгебрі многочленів над полем Галуа. Поліном (многочлен), який можна представити у вигляді добутку поліномів нижчих степенів, називають звідним, в протилежному випадку незвідним. Поліноми у полі двійкових чисел називають незвідними, якщо вони діляться без остачі тільки на себе чи на одиницю. Незвідні поліноми можна записати у вигляді алгебричного поліному, або у вигляді двійкових чи десяткових чисел, наприклад
В основу циклічного кодування закладено використання незвідних поліномів , які для циклічних кодів називають твірними поліномами.
Найпростіший спосіб утворення циклічного коду полягає у множенні заданої кодової комбінації на твірний поліном . Недоліком такого підходу є те, що контрольні розряди m будуть розміщені у найрізноманітніших місцях кодової комбінації. Такий підхід вважається нераціональним, і тому використовується спосіб, який розміщує контрольні розряди після інформаційних
Метод побудови циклічного коду
Множимо вхідну кодову комбінацію на одночлен , що має таку ж степінь, що й твірних поліном
.
Ділимо добуток на твірний поліном
, (3.2)
де – частка від ділення, що має той самий степінь, що й поліном ; – залишок від ділення, що має степінь, не більший від (менший, ніж степінь дільника ).
Множачи цей вираз на та переносячи у другу частину рівняння, згідно правил алгебри двійкового поля, тобто без зміни знаку на зворотній, отримуємо
, (3.3)
де – закодоване повідомлення. Звідси
,
Циклічний декодер
Ідея виявлення помилок у прийнятому циклічному коді полягає у тому, що при відсутності помилок закодоване повідомлення ділиться на твірний поліном без залишку. При цьому контрольні розряди m відкидаються, а інформаційні розряди k використовуються за призначенням.
Обчислюємо залишок від результату ділення за правилами алгебри двійкового поля (алгоритм знаходження цього залишку аналогічний алгоритму п.2 циклічного кодера).
При робимо висновок, що комбінація прийнята без помилок. Наявність залишку свідчить, що комбінація спотворена.
Якщо , тоді виконуємо процедуру виправлення помилок за такою схемою.
Виконуємо підрахунок ваги залишку , тобто підрахунок кількості «1» у залишку.
Якщо вага залишку дорівнює або менша від числа помилок, що виправляються , то прийняту комбінацію додають за модулем 2 до залишку та отримують виправлену комбінацію.
Якщо , то проводять циклічний зсув на один біт вліво, та отриману комбінацію знову ділять на твірний поліном . Якщо вага отриманого залишку , то циклічно зсунуту комбінацію додають до залишку, а потім циклічно зсувають її у зворотну сторону вправо на 1 розряд (повертають на попереднє місце). В результаті отримують виправлену комбінацію.
Якщо після циклічного зсуву на один біт знову , то проводять додаткові зсуви вліво. При цьому після кожного зсуву зсунуту комбінацію ділять на та перевіряють вагу залишку. При виконують дії, вказані в п.b, з тією лише різницею, що зворотних циклічних зсувів вправо роблять стільки, скільки їх було зроблено вліво.
Загальний алгоритм побудови циклічного декодера.
Оголошуємо та ініціалізуємо ідентифікатори ( String^ ErrorText; беззнаковий цілий F_X, G_X, P_X, R_X, first_F_X, first_R_X; int всі решта; проміжні змінні чи маски для F_X, R_X мають теж беззнаковий тип).
Встановлюємо початкові значення для таких змінних:
shift = i_cycling = 0; break_R_X =1; (break_R_X ( інформація про наявність помилки, i_cycling ( кількість виконаних циклів )
Зчитуємо закодоване повідомлення у двійковому вигляді.
Далі у циклі виконуємо такий код:
початок
i_cycling++;
if ( !R_X ) { break_R_X =1; break; }
if (i_cycling ==1 ) { first_R_X = R_X; first_F_X = F_X; }
else if ( first_R_X == R_X && first_F_X == F_X )
{
break_R_X = 2;
ErrorText += L"Помилка зациклення: shift = " + shift;
break;
}
ErrorText += L" R_X = " + R_X;
кінець
Якщо ( W > s_CC) ( цикл повторюємо знову.
Зауваження: недоліком алгоритму виправлення помилок за допомогою циклічних зсувів є можливість виникнення ситуації зациклення: тобто, при циклічному зсуві вліво та діленні на твірний поліном, значення ваги W не зменшується, а через певне число циклів повторюється комбінація початкових значень та . Для уникнення зациклення ми запам’ятовуємо первинні значення та , та у кожному наступному циклі порівнюємо їх з новими. Якщо зауважуємо співпадіння – формуємо інформацію про помилку та завершуємо процес декодування.
Здійснюємо перевірку на помилку зациклення та виконуємо зворотний циклічний зсув .
Якщо (break_R_X2) (
Вилучаємо контрольні розряди.
Виводимо декодоване повідомлення у двійковому вигляді.
Виводимо інформацію про наявні помилки у зовнішньому інформаційному вікні або у компоненті для виводу тексту (наприклад TextBox із заданою опцією Multiline = true).
Якщо (break_R_X > 0) (
MessageBox::Show(ErrorText, "Помилка!!! Циклічний код",
MessageBoxButtons::OK, MessageBoxIcon::Asterisk);
Список ідентифікаторів констант, змінних, функцій, методів, використаних у програмі
G_X – кодова комбінація;
P_X – твірний поліном;
nP_X – кількість розрядів твірного поліному.
R_X – залишок від ділення;
nR_X – кількість розрядів залишку.
F_X – закодоване повідомлення;
W – вага залишку;
s_CC – кількість помилок виправлення;
n_CC – довжина закодованого повідомлення;
k_CC – кількість інформаційних розрядів;
k_bit – значення розряду;
shift – кількість зсувів ( на початку = 0 )
Остаточна версія програми
#pragma once
namespace My3 {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Summary for Form1
///
/// WARNING: If you change the name of this class, you will need to change the
/// 'Resource File Name' property for the managed resource compiler tool
/// associated with all .resx files this class depends on. Otherwise,
/// the designers will not be able to interact properly with localized
/// resources associated with this form.
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Label^ label1;
protected:
private: System::Windows::Forms::Label^ label2;
private: System::Windows::Forms::Button^ button1;
private: System::Windows::Forms::Button^ button2;
private: System::Windows::Forms::TextBox^ textBox1;
private: System::Windows::Forms::TextBox^ textBox2;
private: System::Windows::Forms::TextBox^ textBox3;
private: System::Windows::Forms::Label^ label4;
private: System::Windows::Forms::Label^ label3;
private: System::Windows::Forms::Label^ label5;
private: System::Windows::Forms::Label^ label6;
private: System::Windows::Forms::TextBox^ textBox4;
private: System::Windows::Forms::TextBox^ textBox5;
private: System::Windows::Forms::VScrollBar^ vScrollBar1;
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->label1 = (gcnew System::Windows::Forms::Label());
this->label2 = (gcnew System::Windows::Forms::Label());
this->button1 = (gcnew System::Windows::Forms::Button());
this->button2 = (gcnew System::Windows::Forms::Button());
this->textBox1 = (gcnew System::Windows::Forms::TextBox());
this->textBox2 = (gcnew System::Windows::Forms::TextBox());
this->textBox3 = (gcnew System::Windows::Forms::TextBox());
this->label4 = (gcnew System::Windows::Forms::Label());
this->label3 = (gcnew System::Windows::Forms::Label());
this->label5 = (gcnew System::Windows::Forms::Label());
this->label6 = (gcnew System::Windows::Forms::Label());
this->textBox4 = (gcnew System::Windows::Forms::TextBox());
this->textBox5 = (gcnew System::Windows::Forms::TextBox());
this->vScrollBar1 = (gcnew System::Windows::Forms::VScrollBar());
this->SuspendLayout();
//
// label1
//
this->label1->AutoSize = true;
this->label1->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 15.75F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(204)));
this->label1->Location = System::Drawing::Point(71, 13);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(73, 25);
this->label1->TabIndex = 0;
this->label1->Text = L"G_X->";
this->label1->Click += gcnew System::EventHandler(this, &Form1::label1_Click);
//
// label2
//
this->label2->AutoSize = true;
this->label2->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 15.75F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(204)));
this->label2->Location = System::Drawing::Point(379, 60);
this->label2->Name = L"label2";
this->label2->Size = System::Drawing::Size(51, 25);
this->label2->TabIndex = 1;
this->label2->Text = L"F_X";
this->label2->Click += gcnew System::EventHandler(this, &Form1::label2_Click);
//
// button1
//
this->button1->Location = System::Drawing::Point(17, 165);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(101, 23);
this->button1->TabIndex = 2;
this->button1->Text = L"To Cyclic";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
//
// button2
//
this->button2->Location = System::Drawing::Point(735, 166);
this->button2->Name = L"button2";
this->button2->Size = System::Drawing::Size(96, 23);
this->button2->TabIndex = 3;
this->button2->Text = L"From Cyclic";
this->button2->UseVisualStyleBackColor = true;
this->button2->Click += gcnew System::EventHandler(this, &Form1::button2_Click);
//
// textBox1
//
this->textBox1->Location = System::Drawing::Point(12, 41);
this->textBox1->Name = L"textBox1";
this->textBox1->Size = System::Drawing::Size(377, 20);
this->textBox1->TabIndex = 5;
//
// textBox2
//
this->textBox2->Location = System::Drawing::Point(60, 88);
this->textBox2->Name = L"textBox2";
this->textBox2->Size = System::Drawing::Size(709, 20);
this->textBox2->TabIndex = 6;
//
// textBox3
//
this->textBox3->Location = System::Drawing::Point(464, 41);
this->textBox3->Name = L"textBox3";
this->textBox3->Size = System::Drawing::Size(442, 20);
this->textBox3->TabIndex = 7;
this->textBox3->TextChanged += gcnew System::EventHandler(this, &Form1::textBox3_TextChanged);
//
// label4
//
this->label4->AutoSize = true;
this->label4->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 15.75F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(204)));
this->label4->Location = System::Drawing::Point(591, 9);
this->label4->Name = L"label4";
this->label4->Size = System::Drawing::Size(79, 25);
this->label4->TabIndex = 8;
this->label4->Text = L"-> G_X";
//
// label3
//
this->label3->AutoSize = true;
this->label3->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 15.75F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(204)));
this->label3->Location = System::Drawing::Point(22, 137);
this->label3->Name = L"label3";
this->label3->Size = System::Drawing::Size(106, 25);
this->label3->TabIndex = 9;
this->label3->Text = L"G_x->F_x";
//
// label5
//
this->label5->AutoSize = true;
this->label5->ForeColor = System::Drawing::SystemColors::HotTrack;
this->label5->Location = System::Drawing::Point(344, 146);
this->label5->Name = L"label5";
this->label5->Size = System::Drawing::Size(101, 13);
this->label5->TabIndex = 10;
this->label5->Text = L"маска спотворень";
//
// label6
//
this->label6->AutoSize = true;
this->label6->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 15.75F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(204)));
this->label6->Location = System::Drawing::Point(684, 137);
this->label6->Name = L"label6";
this->label6->Size = System::Drawing::Size(106, 25);
this->label6->TabIndex = 11;
this->label6->Text = L"F_x->G_x";
//
// textBox4
//
this->textBox4->Location = System::Drawing::Point(136, 168);
this->textBox4->Name = L"textBox4";
this->textBox4->Size = System::Drawing::Size(593, 20);
this->textBox4->TabIndex = 12;
this->textBox4->Text = L"0";
this->textBox4->TextChanged += gcnew System::EventHandler(this, &Form1::textBox4_TextChanged);
//
// textBox5
//
this->textBox5->Location = System::Drawing::Point(27, 194);
this->textBox5->Multiline = true;
this->textBox5->Name = L"textBox5";
this->textBox5->Size = System::Drawing::Size(841, 306);
this->textBox5->TabIndex = 13;
//
// vScrollBar1
//
this->vScrollBar1->Location = System::Drawing::Point(846, 194);
this->vScrollBar1->Name = L"vScrollBar1";
this->vScrollBar1->Size = System::Drawing::Size(22, 306);
this->vScrollBar1->TabIndex = 14;
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(918, 540);
this->Controls->Add(this->vScrollBar1);
this->Controls->Add(this->textBox5);
this->Controls->Add(this->textBox4);
this->Controls->Add(this->label6);
this->Controls->Add(this->label5);
this->Controls->Add(this->label3);
this->Controls->Add(this->label4);
this->Controls->Add(this->textBox3);
this->Controls->Add(this->textBox2);
this->Controls->Add(this->textBox1);
this->Controls->Add(this->button2);
this->Controls->Add(this->button1);
this->Controls->Add(this->label2);
this->Controls->Add(this->label1);
this->Name = L"Form1";
this->Text = L"Form1";
this->Click += gcnew System::EventHandler(this, &Form1::Form1_Click);
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
private: System::Void Form1_Click(System::Object^ sender, System::EventArgs^ e) {
if (dynamic_cast<System::Windows::Forms::MouseEventArgs^>(e)->Button==System::Windows::Forms::MouseButtons::Left)
{
label1->Text=Convert::ToString(i1);
i1++;
}
if (dynamic_cast<System::Windows::Forms::MouseEventArgs^>(e)->Button==System::Windows::Forms::MouseButtons::Right)
{
label2->Text=Convert::ToString(i2);
i2++;
}
}
int i1,i2;
private: System::Void label1_Click(System::Object^ sender, System::EventArgs^ e) {
}
private: System::Void label2_Click(System::Object^ sender, System::EventArgs^ e) {
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
short bin_F_X,a,F_X,G_X,P_X,R_X,first_F_X,first_R_X,worker;
String^ c;
int i,nP_X,nR_X,count;
c="";
count=1;
G_X=Convert::Toshort(textBox1->Text,2);
P_X=0x1D1;
nP_X=9;
G_X=G_X<<(nP_X-1);
R_X=G_X;
do
{
worker=R_X;
nR_X=1;
while(worker>1)
{
worker=worker>>1;
nR_X++;
}
R_X=R_X^(P_X<<(nR_X-nP_X));
worker=R_X;
nR_X=1;
while(worker>1)
{
worker=worker>>1;
nR_X++;
}
}
while(nR_X>=nP_X);
F_X=G_X^R_X;
bin_F_X=F_X;
String ^line;
line="";
do
{
if(bin_F_X%2) line="1"+line;
else line="0"+line;
bin_F_X=bin_F_X/2;
}
while(bin_F_X>=2);
if (bin_F_X>0) line="1"+line;
textBox2->Text=line;
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e)
{
String^ ErrorText;
short bin_G_X,F_X,G_X,P_X,R_X,first_F_X,first_R_X,mask,word,worker;
int shift, nP_X=9, i_cycling,break_R_X,W,count,s_CC=6,n_CC=63,k_CC=30,k_bit,nR_X;
shift=i_cycling=0;
break_R_X=1;
F_X=Convert::Toshort(textBox2->Text,2);
P_X=157464165547;
mask=Convert::Toshort(textBox4->Text,2);
F_X=F_X^mask;
do
{
i_cycling++;
R_X=F_X;
do
{
worker=R_X;
nR_X=1;
while (worker>1)
{worker=worker>>1; nR_X++;}
R_X=R_X^(P_X<<(nR_X-nP_X));
worker=R_X;
nR_X=1;
while (worker>1)
{worker=worker>>1; nR_X++;}
}
while(nR_X>=nP_X);
if(!R_X) {break_R_X=1; break;}
if(i_cycling==1) {first_R_X=R_X; first_F_X=F_X;}
else if(first_R_X==R_X&&first_F_X==F_X)
{
break_R_X=2;
ErrorText+=L"Помилка зациклення: shift="+shift;
break;
}
ErrorText+=L" R_X="+R_X;
worker=R_X;
nR_X=1;
while(worker>1)
{
worker=worker>>1;
nR_X++;
}
/*vaga zalusky*/
word=R_X;
int mask2=1;
W=0;
for(int i=0; i<64;i++)
{
if (word&mask2)
W++;
mask2=mask2<<1;
}
/*zsyv vlivo*/
if(W>s_CC)
{
mask=1;
mask=mask<<(n_CC-1);
if(F_X & mask) {k_bit=1; F_X=F_X^mask;}
else k_bit=0;
F_X=F_X<<1;
F_X=F_X|k_bit;
shift++;
}
else F_X=F_X^R_X;
}
while(W>s_CC);
/*************************/
if (break_R_X!=2)
{
for(int i=1; i<=shift;i++)
{
if (F_X&1) k_bit=1;
else k_bit=0;
F_X=F_X>>1;
if (k_bit)
{
mask=1;
mask=mask<<(n_CC-1);
F_X=F_X|mask;
}
}
}
G_X=F_X>>(n_CC-k_CC);//vuly4aemo konrolni rozrjadu
String ^line2;
bin_G_X=G_X;
do
{
if(bin_G_X%2) line2="1"+line2;
else line2="0"+line2;
bin_G_X=bin_G_X/2;
}
while(bin_G_X>=2);
if (bin_G_X>0) line2="1"+line2;
textBox3->Text=line2;
if(break_R_X>0)
{
MessageBox::Show(ErrorText,"Pomulka!!! cukli4nuj kod",
MessageBoxButtons::OK, MessageBoxIcon::Asterisk);
}
array<String^>^ myArr;
myArr=textBox5->Lines;
myArr->Resize(myArr,myArr->Length+2);
textBox5->Lines=myArr;
textBox5->AppendText("Vhidne povidomlennia="+textBox1->Text+" maska spotvorennia="+textBox4->Text
+"Vuhidne povidomlennia="+textBox3->Text+" Infa="+ErrorText);
/**************/
}
private: System::Void textBox3_TextChanged(System::Object^ sender, System::EventArgs^ e) {
}
private: System::Void textBox4_TextChanged(System::Object^ sender, System::EventArgs^ e) {
if(textBox4->SelectionStart!=0) textBox4->SelectionStart--;
}
};
}
Результати виконання програми:
Vhidne povidomlennia=101010111000110101 maska spotvorennia=0Vuhidne povidomlennia=101010111000110101 Infa=
Vhidne povidomlennia=101010111000110101 maska spotvorennia=000000000000001Vuhidne povidomlennia=101010111000110101 Infa= R_X=1
Vhidne povidomlennia=101010111000110101 maska spotvorennia=100000000000000Vuhidne povidomlennia=101010111000110101 Infa= R_X=16384
Vhidne povidomlennia=101010111000110101 maska spotvorennia=000000000000011Vuhidne povidomlennia=101010111000110101 Infa= R_X=3
Vhidne povidomlennia=101010111000110101 maska spotvorennia=110000000000000Vuhidne povidomlennia=101010111000110101 Infa= R_X=24576
Vhidne povidomlennia=101010111000110101 maska spotvorennia=000000000111100Vuhidne povidomlennia=101010111000110101 Infa= R_X=60
Vhidne povidomlennia=101010111000110101 maska spotvorennia=000000100001010Vuhidne povidomlennia=101010111000110101 Infa= R_X=266
Vhidne povidomlennia=101010111000110101 maska spotvorennia=000001100000000Vuhidne povidomlennia=101010111000110101 Infa= R_X=768
Vhidne povidomlennia=101010111000110101 maska spotvorennia=000000000010000Vuhidne povidomlennia=101010111000110101 Infa= R_X=16
Vhidne povidomlennia=101010111000110101 maska spotvorennia=001000000000000Vuhidne povidomlennia=101010111000110101 Infa= R_X=4096