Курсовая работа по предмету "Программирование, компьютеры и кибернетика, ИТ технологии"


Кодирование информации. Код Рида-Малера



Министерство образования и науки Украины

ПОЯСНИТЕЛЬНАЯ ЗАПИСКА

к курсовому проекту

на тему "Кодирование информации. Код Рида-Малера "

по курсу "Кодирование и защита информации"

2003

Содержание

Введение

1 Избыточные коды

2 Алгоритм кодирования Рида-Малера

3 Тестовый пример

Вывод

Библиографический список

Приложение: Текст программы

Введение

Целью настоящей работы является закрепление знаний, получаемых в процессе изучения дисциплины, приобретение необходимых практических навыков применения методов кодирования информации. В данной курсовой работе рассматривается кодирование информации методом Рида-Малера. Код Рида-Малера относится к избыточным кодам. Заданием на данную работу было разработать алгоритм и программу кодирования и декодирования данных кодом Рида-Малера (16,11).

1. Избыточные коды

Избыточные коды - одно из наиболее эффективных средств обеспечения высокой достоверности передаваемых и принимаемых сообщений.

Избыточные коды могут применяться с целью либо только обнаружения возможных ошибок, либо исправления обнаруженных ошибок. Во всех случаях желательно достичь максимальной корректирующей способности. Но в зависимости от конкретного построения кода его способность к исправлению тех или иных ошибок может изменяться в широких пределах.

При некоторых значениях n и k может быть найдено такое удачное построение кода, при котором веса всех разрешенных ненулевых комбинаций мало отличаются друг от друга и от половины максимально возможного веса. При других значениях n и k может оказаться, что для некоторой малой части кодовых комбинаций из их общего числа расстояние оказывается существенно меньшим, чем для большинства других. Поэтому при рассмотрении характеристик кодов можно обнаружить, что близкие по избыточности и числу разрядов коды резко отличаются друг от друга по своей корректирующей способности.

В кодах с одной проверкой на четность содержится всего один проверочный символ. Этот символ выбирается таким, чтобы его сумма по модулю два со всеми информационными символами равнялась нулю. Благодаря такому способу выбора проверочного символа кодовая комбинация содержит четное число единиц. И следовательно признаком искажения кодовой комбинации является нечетность единиц в принятой комбинации. Данный код позволяет только обнаруживать однократные ошибки и все ошибки нечетной кратности.

В кодах с простым повторением положе метод повторения исходной кодовой комбинации. На приемной стороне комбинация складывается с исходной и при нулевой сумме комбинация принимается. Этот код позволяет обнаруживать ошибки, за исключением ошибок в парных элементах.

Корелляционный код. Удваиваются символы, при этом если в разряде информационной части стоит 0, то он заменяется на 01, а 1 - на 10. Сигналом ошибки является появление 00 или 11.

В инверсном коде используется повторение исходной комбинации следующим образом: если комбинация содержит нечетное число единиц, то вместо 1 ставится 0, а всесто 0 - 1. Если четное число единиц, то она удваивается без инверсии. На приемной стороне подсчитывается число единиц и, если оно четно, то вторая половинка инвертируется и складывается с первой. Если же число единиц четно, то вторая складывается с первой и должен получиться 0.

2 Алгоритм кодирования Рида-Малера

Коды Рида-Малера - это блоковые коды, которые строятся следующим образом:

(1) (2) (3),

n-длина блока

K-число информационных символов

d-минимальное кодовое расстояние

m-положительное, условное число не меньше 3

-порядок кода, который всегда меньше, чем m.

Т.е. в зависимости от порядка при одном и том же m можно получить разные коды.

m=4; =1,2,3; n=24=16.

Построение кодов Рида-Маллера сводится к следующему.

В начале строится производящая матрица G, первая строка которой содержит n единиц. Далее следует m строк, совокупность которых удобно рассматривать как (m*n) -матрицу, в качестве столбцов которой выбраны двоичные числа (начиная с нуля). Номера разрядов двоичных чисел удобно считать сверху вниз. Эти m строк определяют векторы первого порядка . Далее идут строки векторов второго порядка, которые получаются из всех произведений двух строк первого порядка, затем - строки третьего порядка, являющиеся всеми произведениями трех строк первого порядка и т д.

Пример: т=3 =2 п=2т=23=8

Для кодирования определяется общее число символов в блоке через информационные символы, суммируя ненулевые позиции соответствующего столбика, образующей матрицы. Единицы в столбцах матрицы G показывают, какие именно информационные символы Uk определяют значение символов Ui кодового слова.

Пусть пришла последовательность:

Получаем: 11101011

Декодирование осуществляется по мажоритарному принципу или принципу большинства.

Декодирование осуществляется вначале для всех информационных символов (кроме 1-го) на основе так называемых парных компонентов. Начинать запись таких уравнений надо с векторов максимального порядка.

В нашем примере =2= первым выписывается Uk5.

Для векторов 2-го порядка парными считаются компоненты:

00 0

01 1

На втором уровне сочетаний каждый 0 соединяется с каждой 1 попарно. Теперь в проверяемое равенство выписываются все объединенные позиции 1-го и 2-го уровней.

Вычисляем символ Uk6

Для Uk7:

При декодировании с помощью векторов 1-го порядка мы также точно пользуемся парными компонентами, но поскольку здесь 1-ый уровень, то мы объединяем просто 0 и 1, стоящую на соответствующих позициях, и, во-вторых, при декодировании в полученных уравнениях используют не исходное, а преобразованное уравнение, которое получается путем сложения по модулю два исходного уравнения и векторов 2-го порядка, (потому что матрица имеет 2-ой порядок),

После этого еще раз преобразуют исходное выражение: к полученному преобразованному выражению прибавляем векторы 1-го порядка, которые содержат единицу в соответствующем информационном разряде.

Если в полученном выражении получили все 1, то значит Uk1=1, а если все 0, то Uk1=0.

Если при передаче произошли искажения, то вычисляемый символ по каждой системе проверок выбирается по мажоритарному принципу, в том числе и для символа Uk1.

3 Тестовый пример

В качестве тестового примера использовалась комбинация 11001010000.

В задании к курсовому проекту указано, что n=16, а k=11. Таким образом получили образующую матрицу, которая имеет следующий вид:

Построение матрицы реализовано программно для заданных n и k.

После кодирования исходной комбинации 11001010000 по полученной образующей матрице получили комбинацию1010111101010000. При этом мы суммируем те разряды исходной комбинации, на соответствующих позициях которых, в рассматриваемом столбце образующей матрицы, стоят единицы. Например, возьмем четвертый столбец. Единицы имеются в разрядах 1,2,3,6. При суммировании этих разрядов получим 0. То есть в закодированной комбинации в четвертом разряде получили 0:

Декодирование осуществляется по мажоритарному признаку, то есть при декодировании каждый разряд комбинации проверяется несколькими уравнениями. Благодаря этому можно избежать ошибок при передаче. Даже если в каком-либо разряде ошибка, она поменяет результат только одного уравнения. А в остальных результат останется тот же.

Вывод

В ходе курсовой работы был исследован простой помехоустойчивый код, а именно код Рида-Малера. Данный код обнаруживает ошибки, но не исправляет их. Рассматривался случай, когда n=16, k=11, поэтому в матрице присутствуют только вектора первого и второго порядка. Однако если появится необходимость использовать также вектора третьего порядка, то образующая матрица станет значительно больше, что не выгодно с точки зрения экономии памяти. При этом также увеличится длина закодированной комбинации, что увеличит время передачи сообщения по каналу связи.

Библиографический список

1. Березюк Н.Т. «Кодирование Информации» - 1978.

2. Конспект лекций по дисциплине «Кодирование и защита информации».

Приложение

Текст программы

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "Unit1.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

const N=16;

const K=11;

char *s;

int f,l[11],l1[16];

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{int i,j;

for (i=0;i<N;i++)

{ StringGrid1->Cells[i][0]=1; }

for (i=0;i<N;i++)

{ StringGrid1->Cells[i][1]=0;

i++; StringGrid1->Cells[i][1]=1; }

for (i=0;i<N;i++)

{ StringGrid1->Cells[i][2]=0;

i++; StringGrid1->Cells[i][2]=0;

i++; StringGrid1->Cells[i][2]=1;

i++; StringGrid1->Cells[i][2]=1; }

for (i=0;i<N;i++)

{ if (i<N/2)

{ StringGrid1->Cells[i][4]=0; }

else

{ StringGrid1->Cells[i][4]=1; }

}

for (i=0;i<N;i++)

{ if (7<i&&i<12||4>i&&i<8)

{ StringGrid1->Cells[i][3]=0; }

else { StringGrid1->Cells[i][3]=1; }

}

int b;

int k1,k2,a=5;

j=1; b=1;

for (j;j<4;j++)

{ for(i=0;i<N;i++)

{ k1=StringGrid1->Cells[i][b].ToInt();

j++; k2=StringGrid1->Cells[i][j].ToInt(); j--;

if (k1==1&&k2==1)

{ StringGrid1->Cells[i][a]=1; }

else

{ StringGrid1->Cells[i][a]=0; }

}

a++; }

b=2; j=2;

for (j;j<4;j++)

{ for(i=0;i<N;i++)

{ k1=StringGrid1->Cells[i][b].ToInt(); j++;

k2=StringGrid1->Cells[i][j].ToInt(); j--;

if (k1==1&&k2==1)

{ StringGrid1->Cells[i][a]=1; }

else

{ StringGrid1->Cells[i][a]=0; }

}

a++;

}

b=3; j=3;

for (j;j<4;j++)

{ for(i=0;i<N;i++)

{ k1=StringGrid1->Cells[i][b].ToInt(); j++;

k2=StringGrid1->Cells[i][j].ToInt(); j--;

if (k1==1&&k2==1)

{ StringGrid1->Cells[i][a]=1; }

else

{ StringGrid1->Cells[i][a]=0; }

}

}

s=" "; Edit1->Text=s;

Edit1->MaxLength=12;

Memo1->Text=s;

Memo1->Lines->Add("U1=Uk1");

Memo1->Lines->Add("U2=Uk1+Uk2");

Memo1->Lines->Add("U3=Uk1+Uk3");

Memo1->Lines->Add("U4=Uk1+Uk2+Uk3+Uk6");

Memo1->Lines->Add("U5=Uk1+Uk4");

Memo1->Lines->Add("U6=Uk1+Uk2+Uk4+Uk7");

Memo1->Lines->Add("U7=Uk1+Uk3+Uk4+Uk9");

Memo1->Lines->Add("U8=Uk1+Uk2+Uk3+Uk4+Uk6+Uk7+Uk9");

Memo1->Lines->Add("U9=Uk1+Uk5");

Memo1->Lines->Add("U10=Uk1+Uk2+Uk5+Uk8");

Memo1->Lines->Add("U11=Uk1+Uk3+Uk5+Uk10");

Memo1->Lines->Add("U12=Uk1+Uk2+Uk3+Uk5+Uk6+Uk8+Uk10");

Memo1->Lines->Add("U13=Uk1+Uk4+Uk5+Uk11");

Memo1->Lines->Add("U14=Uk1+Uk2+Uk4+Uk5+Uk7+Uk8+Uk11");

Memo1->Lines->Add("U15=Uk1+Uk3+Uk4+Uk5+Uk9+Uk10+Uk11");

Memo1->Lines->Add("U16=Uk1+Uk2+Uk3+Uk4+Uk5+Uk6+Uk7+Uk8+Uk9+Uk10+Uk11");}

//---------------------------------------------------------------------------

void __fastcall TForm1::BitBtn1Click(TObject *Sender)

{s=Edit1->Text.c_str();

for(int i=1;i<K+1;i++)

{ l[i-1]=StrToInt(s[i]); }

for (int i=0;i<N;i++)

{ f=0;

for (int j=0;j<K;j++)

{ if (StringGrid1->Cells[i][j]==1)

{ f=l[j]+f; if (f==2) f=0;

}

l1[i]=f;

}

}

for(int i=0;i<N;i++)

{ StringGrid2->Cells[i][0]=l1[i];

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)

{ int ed, nul,i,j,perem[4];

int l2[16]; int edin1=0,edin2=0,edin3=0,edin4=0,edin5=0,edin6=0;

ed=0; nul=0;

for(int i=0;i<N;i++)

{ l1[i]=StringGrid2->Cells[i][0].ToInt(); }

for(i=0;i<N;i++)

{ l2[i]=l1[i]; }

perem[0]=l1[0]+l1[4]+l1[8]+l1[12]; perem[1]=l1[1]+l1[5]+l1[9]+l1[13];

perem[2]=l1[2]+l1[6]+l1[10]+l1[14];perem[3]=l1[3]+l1[7]+l1[11]+l1[15];

for (i=0;i<4;i++)

{ if (perem[i]==1||perem[i]==3)

{ perem[i]=1; ++ed; }

else

{ perem[i]=0; ++nul; }

}

if (nul<ed)

{ StringGrid3->Cells[10][0]=1; edin1=10; }

else

{ StringGrid3->Cells[10][0]=0; }

//------------------------------

ed=0; nul=0;

perem[0]=l1[0]+l1[2]+l1[8]+l1[10]; perem[1]=l1[1]+l1[3]+l1[9]+l1[11];

perem[2]=l1[4]+l1[6]+l1[12]+l1[14]; perem[3]=l1[5]+l1[7]+l1[13]+l1[15];

for (i=0;i<4;i++)

{ if (perem[i]==1||perem[i]==3)

{ perem[i]=1; ++ed; }

else

{ perem[i]=0; ++nul; }

}

if (nul<ed)

{ StringGrid3->Cells[9][0]=1; edin2=9; }

else

{ StringGrid3->Cells[9][0]=0; }

//----------------------------

ed=0; nul=0;

perem[0]=l1[0]+l1[2]+l1[4]+l1[6]; perem[1]=l1[1]+l1[3]+l1[5]+l1[7];

perem[2]=l1[8]+l1[10]+l1[12]+l1[14]; perem[3]=l1[9]+l1[11]+l1[13]+l1[15];

for (i=0;i<4;i++)

{ if (perem[i]==1||perem[i]==3)

{ perem[i]=1; ++ed; }

else

{ perem[i]=0; ++nul; }

}

if (nul<ed)

{ StringGrid3->Cells[8][0]=1; edin3=8; }

else

{ StringGrid3->Cells[8][0]=0; }

//----------------------------

ed=0; nul=0;

perem[0]=l1[0]+l1[1]+l1[8]+l1[9]; perem[1]=l1[2]+l1[3]+l1[10]+l1[11];

perem[2]=l1[4]+l1[5]+l1[12]+l1[13]; perem[3]=l1[6]+l1[7]+l1[14]+l1[15];

for (i=0;i<4;i++)

{ if (perem[i]==1||perem[i]==3)

{ perem[i]=1; ++ed; }

else

{ perem[i]=0; ++nul; }

}

if (nul<ed)

{ StringGrid3->Cells[7][0]=1; edin4=7; }

else

{ StringGrid3->Cells[7][0]=0; }

//---------------------------

ed=0; nul=0;

perem[0]=l1[0]+l1[1]+l1[4]+l1[5]; perem[1]=l1[2]+l1[3]+l1[6]+l1[7];

perem[2]=l1[8]+l1[9]+l1[12]+l1[13]; perem[3]=l1[10]+l1[11]+l1[14]+l1[15];

for (i=0;i<4;i++)

{ if (perem[i]==1||perem[i]==3)

{ perem[i]=1; ++ed; }

else

{ perem[i]=0; ++nul; }

}

if (nul<ed)

{ StringGrid3->Cells[6][0]=1; edin5=6; }

else

{ StringGrid3->Cells[6][0]=0; }

//----------------------------

ed=0; nul=0;

perem[0]=l1[0]+l1[1]+l1[2]+l1[3]; perem[1]=l1[4]+l1[5]+l1[6]+l1[7];

perem[2]=l1[8]+l1[9]+l1[10]+l1[11]; perem[3]=l1[12]+l1[13]+l1[14]+l1[15];

for (i=0;i<4;i++)

{ if (perem[i]==1||perem[i]==3)

{ perem[i]=1; ++ed; }

else

{ perem[i]=0; ++nul; }

}

if (nul<ed)

{ StringGrid3->Cells[5][0]=1; edin6=5; }

else

{ StringGrid3->Cells[5][0]=0; }

//ПРЕОБРАЗОВАНHOЕ СООБЩЕНИЯ

if (edin1!=0)

for (i=0;i<N;i++)

{ l1[i]=l1[i]+StringGrid1->Cells[i][10].ToInt(); }

if (edin2!=0)

for (i=0;i<N;i++)

{ l1[i]=l1[i]+StringGrid1->Cells[i][9].ToInt(); }

if (edin3!=0)

for (i=0;i<N;i++)

{ l1[i]=l1[i]+StringGrid1->Cells[i][8].ToInt(); }

if (edin4!=0)

for (i=0;i<N;i++)

{ l1[i]=l1[i]+StringGrid1->Cells[i][7].ToInt(); }

if (edin5!=0)

for (i=0;i<N;i++)

{ l1[i]=l1[i]+StringGrid1->Cells[i][6].ToInt(); }

if (edin6!=0)

for (i=0;i<N;i++)

{ l1[i]=l1[i]+StringGrid1->Cells[i][5].ToInt(); }

for(i=0;i<N;i++)

{ if (l1[i]==1||l1[i]==3||l1[i]==5||l1[i]==7)

{ l1[i]=1; }

else

{ l1[i]=0; }

}

//-----------------------------------

int edin7=0,edin8=0,edin9=0,edin10=0;

ed=0;nul=0;

int perem1[8];

perem1[0]=l1[0]+l1[8]; perem1[1]=l1[1]+l1[9];

perem1[2]=l1[2]+l1[10]; perem1[3]=l1[3]+l1[11];

perem1[4]=l1[4]+l1[12]; perem1[5]=l1[5]+l1[13];

perem1[6]=l1[6]+l1[14]; perem1[7]=l1[7]+l1[15];

for (i=0;i<4;i++)

{ if (perem1[i]==1||perem1[i]==3||perem1[i]==5||perem1[i]==7)

{ perem1[i]=1; ++ed; }

else

{ perem1[i]=0; ++nul; }

}

if (nul<ed)

{ StringGrid3->Cells[4][0]=1; edin7=6; }

else

{ StringGrid3->Cells[4][0]=0; }

//------------------------------

ed=0; nul=0;

perem1[0]=l1[0]+l1[4]; perem1[1]=l1[1]+l1[5];

perem1[2]=l1[2]+l1[6]; perem1[3]=l1[3]+l1[7];

perem1[4]=l1[8]+l1[12]; perem1[5]=l1[9]+l1[13];

perem1[6]=l1[10]+l1[14]; perem1[7]=l1[11]+l1[15];

for (i=0;i<4;i++)

{ if (perem1[i]==1||perem1[i]==3||perem1[i]==5||perem1[i]==7)

{ perem1[i]=1; ++ed; }

else

{ perem1[i]=0; ++nul; }

}

if (nul<ed)

{ StringGrid3->Cells[3][0]=1; edin8=7; }

else

{ StringGrid3->Cells[3][0]=0; }

//----------------------------------

ed=0; nul=0;

perem1[0]=l1[0]+l1[2]; perem1[1]=l1[1]+l1[3];

perem1[2]=l1[4]+l1[6]; perem1[3]=l1[5]+l1[7];

perem1[4]=l1[8]+l1[10]; perem1[5]=l1[9]+l1[11];

perem1[6]=l1[12]+l1[14]; perem1[7]=l1[13]+l1[15];

for (i=0;i<4;i++)

{ if (perem1[i]==1||perem1[i]==3||perem1[i]==5||perem1[i]==7)

{ perem1[i]=1; ++ed; }

else

{ perem1[i]=0; ++nul; }

}

if (nul<ed)

{ StringGrid3->Cells[2][0]=1; edin9=8; }

else

{ StringGrid3->Cells[2][0]=0; }

//----------------------------

ed=0; nul=0;

perem1[0]=l1[0]+l1[1]; perem1[1]=l1[2]+l1[3];

perem1[2]=l1[4]+l1[5]; perem1[3]=l1[6]+l1[7];

perem1[4]=l1[8]+l1[9]; perem1[5]=l1[10]+l1[11];

perem1[6]=l1[12]+l1[13]; perem1[7]=l1[14]+l1[15];

for (i=0;i<4;i++)

{ if (perem1[i]==1||perem1[i]==3||perem1[i]==5||perem1[i]==7)

{ perem1[i]=1; ++ed; }

else

{ perem1[i]=0; ++nul; }

}

if (nul<ed)

{ StringGrid3->Cells[1][0]=1; edin10=9; }

else

{ StringGrid3->Cells[1][0]=0; }

//2-e преобразование

int l3[11];

if (edin7!=0)

for (i=0;i<N;i++)

{ l1[i]=l1[i]+StringGrid1->Cells[i][4].ToInt(); }

if (edin8!=0)

for (i=0;i<N;i++)

{ l1[i]=l1[i]+StringGrid1->Cells[i][3].ToInt(); }

if (edin9!=0)

for (i=0;i<N;i++)

{ l1[i]=l1[i]+StringGrid1->Cells[i][2].ToInt(); }

if (edin10!=0)

for (i=0;i<N;i++)

{ l1[i]=l1[i]+StringGrid1->Cells[i][1].ToInt(); }

for(i=0;i<N;i++)

{ if (l1[i]==1||l1[i]==3||l1[i]==5)

{ l1[i]=1; }

else

{ l1[i]=0; }

}

//-------------------------------

int perem2=0;

for(i=0;i<N;i++)

{ if (l1[i]==1)

{ ++ed; }

else

{ ++nul; }

}

if (nul<ed)

{ StringGrid3->Cells[0][0]=1; }

else

{ StringGrid3->Cells[0][0]=0; }

}

//---------------------------------------------------------------------------




Не сдавайте скачаную работу преподавателю!
Данную курсовую работу Вы можете использовать для написания своего курсового проекта.

Поделись с друзьями, за репост + 100 мильонов к студенческой карме :

Пишем курсовую работу самостоятельно:
! Как писать курсовую работу Практические советы по написанию семестровых и курсовых работ.
! Схема написания курсовой Из каких частей состоит курсовик. С чего начать и как правильно закончить работу.
! Формулировка проблемы Описываем цель курсовой, что анализируем, разрабатываем, какого результата хотим добиться.
! План курсовой работы Нумерованным списком описывается порядок и структура будующей работы.
! Введение курсовой работы Что пишется в введении, какой объем вводной части?
! Задачи курсовой работы Правильно начинать любую работу с постановки задач, описания того что необходимо сделать.
! Источники информации Какими источниками следует пользоваться. Почему не стоит доверять бесплатно скачанным работа.
! Заключение курсовой работы Подведение итогов проведенных мероприятий, достигнута ли цель, решена ли проблема.
! Оригинальность текстов Каким образом можно повысить оригинальность текстов чтобы пройти проверку антиплагиатом.
! Оформление курсовика Требования и методические рекомендации по оформлению работы по ГОСТ.

Читайте также:
Разновидности курсовых Какие курсовые бывают в чем их особенности и принципиальные отличия.
Отличие курсового проекта от работы Чем принципиально отличается по структуре и подходу разработка курсового проекта.
Типичные недостатки На что чаще всего обращают внимание преподаватели и какие ошибки допускают студенты.
Защита курсовой работы Как подготовиться к защите курсовой работы и как ее провести.
Доклад на защиту Как подготовить доклад чтобы он был не скучным, интересным и информативным для преподавателя.
Оценка курсовой работы Каким образом преподаватели оценивают качества подготовленного курсовика.

Сейчас смотрят :

Курсовая работа Моделирование систем массового обслуживания
Курсовая работа Исследование правового статуса защитника в уголовном судопроизводстве
Курсовая работа Стратегия управления персоналом в ООО "АЛЮСТЭМ"
Курсовая работа Психологические особенности общения младших школьников
Курсовая работа Безопасность и защита населения при авариях на радиационно-опасных объектах
Курсовая работа Представительство в гражданском праве
Курсовая работа Этапы формирования кредитной политики банка
Курсовая работа Себестоимость, прибыль и рентабельность в системе качественных показателей эффективности деятельности предприятия
Курсовая работа Совершенствование организации заработной платы
Курсовая работа Программа диагностики познавательных психических процессов детей младшего школьного возраста
Курсовая работа Лишение свободы как основной вид наказания
Курсовая работа Причины мирового экономического кризиса и пути выхода из него
Курсовая работа Сравнительная характеристика коров черно-пестрой породы различных линий и перспективы их исполь
Курсовая работа Приготовление бутербродов
Курсовая работа Собственный капитал коммерческого банка: состав и порядок формирования