Автор: Пользователь скрыл имя, 02 Апреля 2013 в 19:38, курсовая работа
В данном курсовом проекте были программно реализованы теоретические знания, полученные в течение всего семестра. Были рассмотрены методы нахождения энтропии зависимых и независимых систем, основные способы кодирования информации. В частности были реализованы методы кодирования Шеннона-Фано и кодирование по Хаффману. Реализованы были также основные методы помехоустойчивого кодирования, коды с обнаружением одиночной ошибки, коды с обнаружение и возможностью исправления одиночной ошибки. Рассмотрены способы шифрования входных сообщений, такие как метод шифрования со смещением, и RSA.
Введение…………………………………………………………………………2
Глава 1. Информационные характеристики дискретных
случайных величин…………………………………………………....4
1.1 Задание………….……………………………………………………………4
1.2 Теория………….…………………………………………………………….4
1.3 Программная реализация и алгоритмы…………………………………….5
1.3.1 Запуск программы, входные и выходные данные………………………..5
1.3.2 Алгоритмы и функции……………………………………………………...5
1.3.3 Тестирование………………………………………………………………..7
Глава 2. Оптимальное кодирование……………………………………………..8
2.1 Задание………………………………………………………………………...8
2.2 Теория…………………………………………………………………………8
2.3 Программная реализация и алгоритмы…………………………………….10
2.3.1 Запуск программы, входные и выходные данные .……………………...10
2.3.2 Алгоритмы и функции…………………………………………………….10
2.3.3 Тестирование………………………………………………………………16
Глава 3. Помехоустойчивое кодирование………………...……………………19
3.1 Задание……………………………………………………………………….19
3.2 Теория………………………………………………………………………...19
3.3 Программная реализация и алгоритмы…………………………………….23
3.3.1 Запуск программы, входные и выходные данные .……………………...23
3.3.2 Алгоритмы и функции…………………………………………………….23
3.3.3 Тестирование………………………………………………………………27
Глава 4. Шифрование данных…….…………………………………………….27
4.1 Задание……………………………………………………………………….27
4.2 Теория………………………………………………………………………...27
4.3 Программная реализация и алгоритмы…………………………………….30
4.3.1 Запуск программы, входные и выходные данные .……………………...30
4.3.2 Алгоритмы и функции…………………………………………………….30
4.3.3 Тестирование………………………………………………………………34
5. Заключение……………………………………………………………………35
Приложение 1……………………………………………………………………36
Приложение 2……………………………………………………………………37
Приложение 3……………………………………………………………………41
Приложение 4……………………………………………………………………43
printf("%d ",c);
}
puts("");
}
//ниже правильным образом считаются вероятности Х/У и У/Х
puts("\n\nUslovnie veroyatnosti");
printf("X/Y a b c d \n");
for (ch1=0;ch1<=3;ch1++) {
printf("%c ",(char)('a'+ch1));
for (ch2=0;ch2<=3;ch2++) {
verXY[ch1][ch2]=(double)cXY[
printf("%.3f ",verXY[ch1][ch2]);
}
puts("");
}
puts("\n\nUslovnie veroyatnosti");
printf("Y/X a b c d \n");
for (ch1=0;ch1<=3;ch1++) {
printf("%c ",(char)('a'+ch1));
for (ch2=0;ch2<=3;ch2++) {
verYX[ch1][ch2]=(double)cXY[
printf("%.3f ",verYX[ch1][ch2]);
}
puts("");
}
//По матрицам P(X/Y) и P(Y/X) считаем H(X/Y) и H(Y/X)
for (j=0;j<4;j++) {
temp=0.0;
for (i=0;i<4;i++)
if (verXY[i][j]>=0.0000000001) temp+=-verXY[i][j]*log(verXY[
entXlY+=verY[j]*temp;
}
printf("\nEntropiya X/Y %.3f",entXlY);
for (j=0;j<4;j++) {
temp=0.0;
for (i=0;i<4;i++)
if (verYX[i][j]>=0.0000000001) temp+=-verYX[i][j]*log(verYX[
entYlX+=verX[j]*temp;
}
printf("\nEntropiya Y/X %.3f",entYlX);
printf("\nEntropiya nezav (X,Y) %.3f",entX+entY);
printf("\nEntropiya zav (X,Y) %.3f %.3f",entXlY+entY,entYlX+entX)
printf("\nVzaimnaya inf Y->X %.3f",entX-entXlY);
printf("\nVzaimnaya inf X->Y %.3f",entY-entYlX);
printf("\nOb`em %d",2*strlen(a));
getch();
}
Приложение 2. Листинг tik_lab2.
#include "stdio.h"
#include "conio.h"
#include "string.h"
#include "math.h"
//Максимальная длина строки
const int MAXL=150;
//структура сочетания
typedef struct
{
char x[MAXL];//комбинация
char code[MAXL];//код
double ver;//вероятность
} soch;
void show(soch *sochet[],int n);
//Кодирование сообщения по готовым кодам
//soch- сочетания, n- колво, in- входная строка, out- полученный код, k- количество символов в комбинации
//Примечание: Из строки берётся количество символов кратное k, остальные отбрасываются
void encode(soch *sochet[],int n,char in[MAXL],char out[MAXL*5],int k) {
char tofind[MAXL];
int i=0,j;
out[0]='\0';
while (i<strlen(in)/k*k) {//отбрасываем неполные комбинации
strncpy(tofind,in+i,k);tofind[
for (j=0;(strcmp(tofind,sochet[j]-
strcpy(out+strlen(out),sochet[
i+=k;
}
}
//Декодирование сообщения по готовым кодам
void decode(soch *sochet[],int n,char in[MAXL*5],char out[MAXL]) {
char tofind[MAXL];
soch *sortsochet[MAXL]; //копия входных сочетаний, будет отсортирована
int i=0,j,ncode=0,scode=0;
char ch;
out[0]='\0';
//Sort
for(i=0; i<n; i++) sortsochet[i]=sochet[i];
soch *t;
for(i=0; i<n; i++) {
for(int j=n-1; j>i; j--)
if (strcmp(sortsochet[j-1]->code,
t=sortsochet[j];sortsochet[j]=
}
}
//
i=0;
while (i<strlen(in)) {//пока не прочитаем всё сообщение
ch=in[i];//берём символ текущий (1 или 0)
//находим подходящую
while (sortsochet[ncode]->code[
ncode++;
scode++;//сдвигаемся к следующему символу
//Если код полный, значит мы нашли комбинацию символов
if (sortsochet[ncode]->code[
strcpy(out+strlen(out),
scode=0;
ncode=0;
}
i++;
}
}
//вывод кодов
void show(soch *sochet[],int n)
{
double sredn=0,//среднее
ent=0;//энтропия
for (int i=0; i<n; i++) {
sredn+=sochet[i]->ver*strlen(
ent-=sochet[i]->ver*log(
printf("\n%s %.6f %s",sochet[i]->x,sochet[i]->
}
printf("\nEntropiya %f\n",ent);//выводим энтропию
printf("Sr dlina %f\n",sredn);//среднюю длину
printf("Izbitochnost %f\n",1-ent/sredn);//
}
//Построение кодов хаффмана
void haffman(soch *sochet[],int n){
//Сортируем вероятности (методом пузырька)
soch *t;
for(int i=0; i<n; i++)
for(int j=n-1; j>i; j--)
if ((sochet[j-1]->ver < sochet[j]->ver)){
t=sochet[j];sochet[j]=sochet[
}
//создаем дерево (с помощью параллельных массивов)
int der_rod[2*MAXL];//родитель вершины
int der_bit[2*MAXL]={0};//бит вершины (символ)
double der_ver[2*MAXL]={0};//
int res_ver[2*MAXL]={0};
int res_i[2*MAXL]={0};
//задаем листья (все исходные комбинации)
for (int i=0; i<n; i++) {
der_bit[i]=-1;
der_rod[i]=-1;
der_ver[i]=sochet[i]->ver;
}
//начинаем кодировку
int count=n;
while (1) {
int minn1,minn2;
//находим минимальные
вершины без кодов (и
//первая вершина
double min=2.0;
for (int i=0; i<count; i++) {
if (der_bit[i]==-1 && der_ver[i]<=min) {min=der_ver[i];minn1=i;}
}
//вторая вершина
min=2.0;
for (int i=0; i<count; i++) {
if (der_bit[i]==-1 && der_ver[i]<=min && minn1!=i) {min=der_ver[i];minn2=i;}
}
//присваиваем им коды
der_bit[minn1]=1;
der_bit[minn2]=0;
//если постороенно полное дерево, то выходим
if (count==2*n-2) break;//условие выхода
//иначе добавляем родителя
der_bit[count]=-1;//бит родителя пока неизвестен
der_rod[count]=-1;//родителей пока нет
der_rod[minn1]=count;//
der_rod[minn2]=count;//
der_ver[count]=der_ver[minn1]+
count++;
}
//от каждого листа идём к корню дерева и запоминаем код
for (int i=0; i<n; i++) {
int p=i,k=0;
while (p!=-1) {//пока не придём к корню
sochet[i]->code[k]='0'+der_
p=der_rod[p];
k++;
}
sochet[i]->code[k]='\0';//
//"разворачиваем" код,
т.к. он получился задом
for (int j=0;j<k/2;j++) {
char temp=sochet[i]->code[j];
sochet[i]->code[j]=sochet[i]->
sochet[i]->code[k-1-j]=temp;
}
}
}
//Построение кодов Шеннона-
//Аргументы:указатель на
сочетания,начало и конец
void fano_rec(soch *sochet[],int first,int last,double sump,int k){
double sum=0,//сумма первой группы
razn=2.0;//разница между группами
int i=first,//номер рассматриваемой комбинации
ss=-1;//количество комбинаций в первой группе
//в первую группу заносим новые комбинации, пока разница сумм вероятностей у групп не будет минимальна
//Т.е. если при добавлении
новой комбинации разница
while (((razn > fabs(sump-2*(sum+sochet[i]->
sum+=sochet[i]->ver;//
sochet[i]->code[k]='0';//пишем нолm в код комбинации (она уже в первой группе)
ss+=1;
razn=fabs(sump-2*sum);
//во второй групппе сумма (sump-sum), в первой sum, разница равна (sump-sum-sum) по модулю
i++;
}
while (i<=last) {sochet[i]->code[k]='1';i++;}/
//запускаем рекурсию в
каждой из групп или
if (ss>0) fano_rec(sochet,first,first+
else sochet[first]->code[k+1]='\0';
if (last-first-ss>1) fano_rec(sochet,first+ss+1,
else sochet[last]->code[k+1]='\0';
}
//Построение кодов Шеннона-
void fano(soch *sochet[],int n){
//Сортируем вероятности
soch *t;
for(int i=0; i<n; i++)
for(int j=n-1; j>i; j--)
if ((sochet[j-1]->ver < sochet[j]->ver)){
t=sochet[j];sochet[j]=sochet[
}
//Запускаем рекурсивную функцию
fano_rec(sochet,0,n-1,1.0,0);
}
//Основная функция
int main(){
char str[]="
int i,j,n1=0,n2=0,n3=0;
char ch,ch1,ch2,ch3;
int c;
double ent=0;
double p[4];
soch *sochet3[64],*sochet2[16], *sochet1[4];
puts("Veroyatnosti");
printf(" p c\n");
for (ch='a';ch<='d';ch++) {
printf("%c ",ch);
c=0;
for (i=0;i<=strlen(str);i++)
if (str[i]==ch) c++;
p[ch-'a']=(double)c/strlen(
printf("%.3f %d\n",p[ch-'a'],c);
ent+=-p[ch-'a']*log(p[ch-'a'])
}
printf("Entropiya %.3f\n",ent);
//формирование сочетаний
for (ch1='a';ch1<='d';ch1++) {
sochet1[n1]= new soch;
sochet1[n1]->ver=p[ch1-'a'];
sochet1[n1]->x[0]=ch1;
sochet1[n1]->x[1]='\0';
n1++;
for (ch2='a';ch2<='d';ch2++) {
sochet2[n2]= new soch;
sochet2[n2]->ver=p[ch1-'a']*p[
sochet2[n2]->x[0]=ch1;
sochet2[n2]->x[1]=ch2;
sochet2[n2]->x[2]='\0';
n2++;
for (ch3='a';ch3<='d';ch3++) {
sochet3[n3]= new soch;
sochet3[n3]->ver=p[ch1-'a']*p[
sochet3[n3]->x[0]=ch1;
sochet3[n3]->x[1]=ch2;
sochet3[n3]->x[2]=ch3;
sochet3[n3]->x[3]='\0';
n3++;
}
}
}
char kod[MAXL*5]={0};
char source[MAXL]={0};
fano(sochet1,n1);
fano(sochet2,n2);
fano(sochet3,n3);
printf("\nFano 1sim:");
show(sochet1,n1);
encode(sochet1,n1,str,kod,1);
decode(sochet1,n1,kod,source);
printf("\nFano 2sim:");
show(sochet2,n2);
encode(sochet2,n2,str,kod,2);
decode(sochet2,n2,kod,source);
printf("\nFano 3sim:");
show(sochet3,n3);
encode(sochet3,n3,str,kod,3);
decode(sochet3,n3,kod,source);
haffman(sochet1,n1);
haffman(sochet2,n2);
haffman(sochet3,n3);
printf("\nHaffman 1sim:");
show(sochet1,n1);
encode(sochet1,n1,str,kod,1);
decode(sochet1,n1,kod,source);
printf("\nHaffman 2sim:");
show(sochet2,n2);
encode(sochet2,n2,str,kod,2);
decode(sochet2,n2,kod,source);
printf("\nHaffman 3sim:");
show(sochet3,n3);
encode(sochet3,n3,str,kod,3);
decode(sochet3,n3,kod,source);
getch();
for (i=0;i<n1;i++) delete sochet1[i];
for (i=0;i<n2;i++) delete sochet2[i];
for (i=0;i<n3;i++) delete sochet3[i];
}
Приложение 3. Листинг tik_lab3.
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <math.h>
const int MAXL=200;
//Получение циклического кода
void get_cicl_code(char *comb, char *poly, int r, char *code) {
__int64 a=0,b=0,c=2;
strcpy(code,comb);
//припишем к комбинации нужное количество нулей
for (int i=0;i<r;i++) {
code[strlen(code)+1]='\0';
code[strlen(code)]='0';
}
//проведем деление по модулю
for (int i=0;i<strlen(code)-strlen(
if (code[i]=='0') continue;
else {
for (int j=0;j<strlen(poly);j++) {
if (poly[j]=='1') {
if (code[i+j]=='1')
code[i+j]='0';
else code[i+j]='1';
}
}
}
}
//припишем
for (int i=0;i<strlen(comb);i++) {
code[i]=comb[i];
}
}
//Получение номера разряда с ошибкой
int get_cicl_mistake(char *code, char *poly) {
char temp[MAXL],ostatok[MAXL],
strcpy(temp,code);
//проведем деление по модулю
for (int i=0;i<strlen(temp)-strlen(
if (temp[i]=='0') continue;
else {
for (int j=0;j<strlen(poly);j++) {
if (poly[j]=='1') {
if (temp[i+j]=='1')
temp[i+j]='0';
else temp[i+j]='1';
}
}
}
}
//перепишем остаток
for (int i=0;i<strlen(poly)-1;i++)
ostatok[i]=temp[strlen(temp)-
ostatok[strlen(poly)-1]='\0';
//
temp[0]='1';
for (int i=0;i<strlen(code)-1;i++) temp[i+1]='0';
temp[strlen(code)]='\0';
int c=-1;
//проведем деление по модулю
for (int i=0;i<strlen(temp)-strlen(
if (temp[i]=='1'){
for (int j=0;j<strlen(poly);j++) {
if (poly[j]=='1') {
if (temp[i+j]=='1')
temp[i+j]='0';
else temp[i+j]='1';
}
}
}
for (int j=0;j<strlen(ostatok);j++) ostatok2[j]=temp[1+i+j];//
ostatok2[strlen(ostatok)]='\0'
if (strcmp(ostatok,ostatok2)==0) {c=i;break;}//если он равен полученному прежде, то выходим
}
if (c!=-1)
return strlen(temp)-strlen(poly)-c+1;
else return -1;
}
//Код с постоянным весом
void get_code_ves(char *comb,char *code,int cz, int co) {
strcpy(code,comb);
int ccz=0,cco=0;
for (int i=0;i<strlen(code);i++) {
if (code[i]=='0') ccz++; else cco++;
}
for (int i=0;i<cz-ccz;i++) {
code[strlen(code)+1]='\0';
code[strlen(code)]='0';
}
for (int i=0;i<co-cco;i++) {
code[strlen(code)+1]='\0';
code[strlen(code)]='1';
}
}
//Код с проверкой на четность
void get_code_chetn(char *comb,char *code) {
strcpy(code,comb);
int ccz=0,cco=0;
for (int i=0;i<strlen(code);i++) {
if (code[i]=='0') ccz++; else cco++;
}
if (cco%2==1) {
code[strlen(code)+1]='\0';
code[strlen(code)]='1';
} else {
code[strlen(code)+1]='\0';
code[strlen(code)]='0';
}
}
//Код с инверсией
void get_code_invers(char *comb,char *code) {
strcpy(code,comb);
int ccz=0,cco=0;
for (int i=0;i<strlen(code);i++) {
if (code[i]=='0') ccz++; else cco++;
}
if (cco%2==0) {
for (int i=0;i<strlen(comb);i++)
code[i+strlen(comb)]=comb[i]; }
else {
for (int i=0;i<strlen(comb);i++)
if (comb[i]=='0') code[i+strlen(comb)]='1'; else code[i+strlen(comb)]='0';
}
code[strlen(comb)*2-1]='\0';
}
//Код с удвоением
void get_code_udv(char *comb,char *code) {
strcpy(code,comb);
int ccz=0,cco=0;
for (int i=0;i<strlen(comb);i++) {
if (comb[i]=='0') {
code[i*2]='0';
code[i*2+1]='1';
} else {
code[i*2]='1';
code[i*2+1]='0';
}
}
code[strlen(comb)*2]='\0';
}
//Код грея
void get_code_grei(char *comb,char *code) {
strcpy(code,comb);
int ccz=0,cco=0;
for (int i=1;i<strlen(comb);i++) {
if (comb[i-1]=='1') {
if (code[i]=='0') code[i]='1'; else code[i]='0';
}
}
}
int main(){
char comb[]="10010";
char g[]="10011";
char code[MAXL];
int r=4;
printf("\nkomb %s",comb);
get_cicl_code(comb,g,r,code);
printf("\ncycle code %s",code);
code[3]='0';
int raz=get_cicl_mistake(code,g);
printf("\nrazr %d",raz);
get_code_ves(comb,code,15,15);
printf("\ncode_ves %s",code);
get_code_chetn(comb,code);
printf("\ncode_chetn %s",code);
get_code_invers(comb,code);
printf("\ncode_invers %s",code);
get_code_udv(comb,code);
printf("\ncode_udv %s",code);
get_code_grei(comb,code);
printf("\ncode_grey %s",code);
getch();
return 0;
}
Приложение 4. Листинг ЛабТиик№4.
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <clocale>
#include <iostream>
#include <cstdlib>
using namespace std;
struct alphabet
{
char name;
int code;
};
void ABCFeling(struct alphabet A[])
{
A[0].name='a';
A[1].name='b';
A[2].name='c';
A[3].name='d';
A[4].name='e';
A[5].name='f';
A[6].name='g';
A[7].name='h';
A[8].name='i';
A[9].name='j';
A[10].name='k';
A[11].name='l';
A[12].name='m';
A[13].name='n';
A[14].name='o';
A[15].name='p';
A[16].name='q';
A[17].name='r';
A[18].name='s';
A[19].name='t';
A[20].name='u';
A[21].name='v';
A[22].name='w';
A[23].name='x';
A[24].name='y';
A[25].name='z';
for(int i=0;i<26;i++) A[i].code=0;
for(int i=0;i<26;i++) A[i].code=i+1;
//////////test
//for(int i=0;i<26;i++) printf("%c %d\n",A[i].name,A[i].code);
}
void GetClue(int C[],int n,struct alphabet ABC[])
{
char s[12];
puts("Введите ключ");
scanf("%s",&s);
for(int i=0;i<n; i++)
{
for(int j=0;j<26;j++)
if(s[i]==ABC[j].name) C[i]=ABC[j].code;
}
/////test
// puts("Kluch\n"); for(int i=0;i<n; i++) printf("%d ",C[i]);
}
void Shifrovanie(struct alphabet STR[],int n, int C[],int nc,struct alphabet ABC[])
Информация о работе Курсовая работа по «Теории информации и кодирования»