信息论课程设计.docx

上传人:b****8 文档编号:11126990 上传时间:2023-02-25 格式:DOCX 页数:25 大小:125.15KB
下载 相关 举报
信息论课程设计.docx_第1页
第1页 / 共25页
信息论课程设计.docx_第2页
第2页 / 共25页
信息论课程设计.docx_第3页
第3页 / 共25页
信息论课程设计.docx_第4页
第4页 / 共25页
信息论课程设计.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

信息论课程设计.docx

《信息论课程设计.docx》由会员分享,可在线阅读,更多相关《信息论课程设计.docx(25页珍藏版)》请在冰豆网上搜索。

信息论课程设计.docx

信息论课程设计

信息论课程设计

 

专业:

信息安全

班级:

1001

学号:

3100604017

姓名:

段惠文

报告日期:

2012年6月18

 

一、任务说明

1、判定唯一可译码

输入:

任意的一个码(即已知码字个数及每个具体的码字)

输出:

判决结果(是/不是)

输入文件:

in1.txt,含至少2组码,每组的结尾为”$”符

输出文件:

out1.txt,对每组码的判断结果

说明:

为了简化设计,可以假定码字为0,1串

参考算法伪代码:

Forall

do

if

的前缀then

将相应的后缀作为一个尾随后缀放入集合

Endif

Endfor

Loop

Forall

do

Forall

do

if

的前缀then

将相应的后缀作为一个尾随后缀放入集合

Elseif

的前缀then

将相应的后缀作为一个尾随后缀放入集合

Endif

Endfor

Endfor

If

then

Returnfalse

ElseifF中未出现新的元素then

Returntrue

Endif

//能走到这里,说明F中有新的元素出现,需继续

Endloop

2、Shannon编码

输入:

信源符号个数q,信源的概率分布P

输出:

每个信源符号对应的Shannon编码的码字

输入文件:

in2.txt,含至少两组输入,每组包含信源符号个数q和q个信源的概率分布值

输出文件:

out2.txt,对每组输入的编码结果

参考算法伪代码:

降序排列

ForI=1toq

将累加概率

(十进制小数)变换成二进制小数

取小数点后

个二进制数字作为第i个消息的码字

Endfor

3.循环码的编码与译码:

要求:

(7,4)非系统循环码,其中,g(x)=x3+x+1,先编码(多项式乘法),再译码

输入文件:

in6.txt,包括至少两组待编码的信息元序列

输出文件:

out6.txt,对每组信息元的编码和再译码结果

二、问题分析、实现原理

1、判定唯一可译码

根据唯一可译码的判别方法,利用数据结构所学的知识,定义字符串数据类型并利用指针进行编程来实现算法。

算法:

1、考察C中所有的码字,若Wi是Wj的前缀,则将对应的后缀作为一个尾随后缀码放入集合Fi+1中;

2、考察C和Fi俩个集合,若Wi∈C是Wj∈F的前缀或Wi∈F是Wj∈C的前缀,则将相应的后缀作为尾随后缀码放入集合Fi+1中;

3、F=∪Fi即为码C的尾随后缀集合;

4、若F中出现了C中的元素,算法终止,返回假(C不是唯一可译码);否则若F中没有出现新的元素,则返回真。

2、Shannon编码

信源符号按概率从大到小顺序排列

对信源符号求累加和,表达式:

Pi=Pi-1+P(Xi)

求自信息量来确定码字长度,自信息量I(xi)=-log(p(xi)),码字长度取大于等于自信息量得最下整数。

将累加和用二进制数表示,并取小数点后对应码长度的数做为码字

3.循环码的编码与译码

1.编码过程

    在编码时,首先需要根据给定循环码的参数确定生成多项式g(x),也就是从

的因子中选一个(n-k)次

多项式作为g(x);然后,利用循环码的编码特点,即所有循环码多项式A(x)都可以被g(x)整除,来定义生成多项

式g(x)。

    根据上述原理可以得到一个较简单的系统:

设要产生(n,k)循环码,m(x)表示信息多项式,循环码编码方法

则其次数必小于k,而

·m(x)的次数必小于n,用

·m(x)除以g(x),可得余数r(x),r(x)的次数必小于

(n-k),将r(x)加到信息位后作监督位,就得到了系统循环码。

下面就将以上各步处理加以解释。

    

(1)用

乘m(x)。

这一运算实际上是把信息码后附加上(n-k)个“0”。

例如,信息码为110,它相当

于m(x)=

+x。

当n-k=7-3=4时,

·m(x)=

+

,它相当于1100000。

而希望的到得系统循环码多项

式应当是A(x)=

·m(x)+r(x)。

    

(2)求r(x)。

由于循环码多项式A(x)都可以被g(x)整除,也就是:

 

                   因此,用

·m(x)除以g(x),就得到商Q(x)和余式r(x),即

              

   

    这样就得到了r(x)。

    (3)编码输出系统循环码多项式A(x)为:

                             2.译码过程

    对于接收端译码的要求通常有两个:

检错与纠错。

达到检错目的的译码十分简单,可以由式(8-37),通过

判断接收到的码组多项式B(x)是否能被生成多项式g(x)整除作为依据。

当传输中未发生错误时,也就是接收的码

组与发送的码组相同,即A(x)=B(x),则接收的码组B(x)必能被g(x)整除;若传输中发生了错误,则A(x)≠B(x)

,B(x)不能被g(x)整除。

因此,可以根据余项是否为零来判断码组中有无错码。

    需要指出的是,有错码的接收码组也有可能被g(x)整除,这时的错码就不能检出了。

这种错误被称为不可检

错误,不可检错误中的错码数必将超过这种编码的检错能力。

    在接收端为纠错而采用的译码方法自然比检错要复杂许多,因此,对纠错码的研究大都集中在译码算法上。

我们知道,校正子与错误图样之间存在某种对应关系。

如同其它线性分组码,循环编码和译码可以分三步进行:

    

(1)由接收到的码多项式B(x)计算校正子(伴随式)多项式S(x);

    

(2)由校正子S(x)确定错误图样E(x);

    (3)将错误图样E(x)与B(x)相加,纠正错误。

    上述第

(1)步运算和检错译码类似,也就是求解B(x)整除g(x)的余式,第(3)步也很简单。

因此,纠错码

译码器的复杂性主要取决于译码过程的第

(2)步。

    基于错误图样识别的译码器称为梅吉特译码器,它的原理图如图8-7所示。

错误图样识别器是一个具有(n-k)

个输入端的逻辑电路,原则上可以采用查表的方法,根据校正子找到错误图样,利用循环码的上述特性可以简化识

三.实现源码

1、判定唯一可译码

#include

#include

#include

structstrings

{

char*string;

structstrings*next;

};

structstringsFstr,*Fh,*FP;

//输出当前集合

Voidoutputstr(strings*str)

{

do

{

cout<string<

str=str->next;

}while(str);

cout<

}

IntMIN(inta,intb)

{returna>b?

b:

a;}

intMAX(inta,intb)

{returna>b?

a:

b;}

#definelength_a(strlen(CP))

#definelength_b(strlen(tempPtr))

//判断一个码是否在一个码集合中,在则返回0,不在返回1

intcomparing(strings*st_string,char*code)

{

while(st_string->next)

{

st_string=st_string->next;

if(!

strcmp(st_string->string,code))

return0;

}

return1;

}

//判断两个码字是否一个是另一个的前缀,如果是则生成后缀码

Voidhouzhui(char*CP,char*tempPtr)

{

if(!

strcmp(CP,tempPtr))

{

cout<<"集合C和集合F中有相同码字:

"<

<

<<"不是唯一可译码码组!

"<

exit

(1);

}

if(!

strncmp(CP,tempPtr,MIN(length_a,length_b)))

{

structstrings*cp_temp;

cp_temp=new(structstrings);

cp_temp->next=NULL;

cp_temp->string=newchar[abs(length_a-length_b)+1];

char*longstr;

longstr=(length_a>length_b?

CP:

tempPtr);//将长度长的码赋给longstr

//取出后缀

for(intk=MIN(length_a,length_b);k

cp_temp->string[k-MIN(length_a,length_b)]=longstr[k];

cp_temp->string[abs(length_a-length_b)]=NULL;

//判断新生成的后缀码是否已在集合F里,不在则加入F集合

if(comparing(Fh,cp_temp->string))

{

FP->next=cp_temp;

FP=FP->next;

}

}

}

voidmain()

{

//功能提示和程序初始化准备

cout<<"\t\t唯一可译码的判断!

\n"<

structstringsCstr,*Ch,*CP,*tempPtr;

Ch=&Cstr;

CP=Ch;

Fh=&Fstr;

FP=Fh;

charc[]="C:

";

Ch->string=newchar[strlen(c)];

strcpy(Ch->string,c);

Ch->next=NULL;

charf[]="F:

";

Fh->string=newchar[strlen(f)];

strcpy(Fh->string,f);

Fh->next=NULL;

//输入待检测码的个数

IntCnum;

cout<<"输入待检测码的个数:

";

cin>>Cnum;

cout<<"输入待检测码"<

for(inti=0;i

{

cout<

";

chartempstr[10];

cin>>tempstr;

CP->next=new(structstrings);

CP=CP->next;

CP->string=newchar[strlen(tempstr)];

strcpy(CP->string,tempstr);

CP->next=NULL;

}

outputstr(Ch);

CP=Ch;

while(CP->next->next)

{

CP=CP->next;

tempPtr=CP;

do

{

tempPtr=tempPtr->next;

houzhui(CP->string,tempPtr->string);

}while(tempPtr->next);

}

outputstr(Fh);

structstrings*Fbegin,*Fend;

Fend=Fh;

while

(1)

{

if(Fend==FP)

{

cout<<"是唯一可译码码组!

"<

exit

(1);

}

Fbegin=Fend;

Fend=FP;

CP=Ch;

while(CP->next)

{

CP=CP->next;

tempPtr=Fbegin;

for(;;)

{

tempPtr=tempPtr->next;

houzhui(CP->string,tempPtr->string);

if(tempPtr==Fend)

break;

}

}

outputstr(Fh);//输出F集合中全部元素

}

}

2、Shannon编码

#include

#include

#include

#definemax_CL10/*maxsizeoflengthofcode*/

#definemax_PN6/*输入序列的个数*/

typedeffloatdatatype;

typedefstructSHNODE{

datatypepb;/*第i个消息符号出现的概率*/

datatypep_sum;/*第i个消息符号累加概率*/

intkl;/*第i个消息符号对应的码长*/

intcode[max_CL];/*第i个消息符号的码字*/

structSHNODE*next;

}shnolist;

datatypesym_arry[max_PN];/*序列的概率*/

voidpb_scan();/*得到序列概率*/

voidpb_sort();/*序列概率排序*/

voidvaluelist(shnolist*L);/*计算累加概率,码长,码字*/

voidcodedisp(shnolist*L);

voidpb_scan()

{

inti;

datatypesum=0;

printf("input%dpossible!

\n",max_PN);

for(i=0;i

{printf(">>");

scanf("%f",&sym_arry[i]);

sum=sum+sym_arry[i];

}

/*判断序列的概率之和是否等于,在实现这块模块时,scanf()对float数的缺陷,故只要满足.99

if(sum>1.0001||sum<0.99)

{printf("sum=%f,summust(<0.999

pb_scan();

}

}

/*选择法排序*/

voidpb_sort()

{

inti,j,pos;

datatypemax;

for(i=0;i

{

max=sym_arry[i];

pos=i;

for(j=i+1;j

if(sym_arry[j]>max)

{

max=sym_arry[j];

pos=j;

}

sym_arry[pos]=sym_arry[i];

sym_arry[i]=max;

}

}

voidcodedisp(shnolist*L)

{

inti,j;

shnolist*p;

datatypehx=0,KL=0;/*hx存放序列的熵的结果,KL存放序列编码后的平均码字的结果*/

p=L->next;

printf("num\tgailv\tsum\t-lb(p(ai))\tlenth\tcode\n");

printf("\n");

for(i=0;i

{

printf("a%d\t%1.3f\t%1.3f\t%f\t%d\t",i,p->pb,p->p_sum,-3.332*log10(p->pb),p->kl);

j=0;

for(j=0;jkl;j++)

printf("%d",p->code[j]);

printf("\n");

hx=hx-p->pb*3.332*log10(p->pb);/*计算消息序列的熵*/

KL=KL+p->kl*p->pb;/*计算平均码字*/

p=p->next;

}

printf("H(x)=%f\tKL=%f\nR=%fbit/code",hx,KL,hx/KL);/*计算编码效率*/

}

shnolist*setnull()

{shnolist*head;

head=(shnolist*)malloc(sizeof(shnolist));

head->next=NULL;

return(head);

}

shnolist*my_creat(datatypea[],intn)

{

shnolist*head,*p,*r;

inti;

head=setnull();

r=head;

for(i=0;i

{p=(shnolist*)malloc(sizeof(shnolist));

p->pb=a[i];

p->next=NULL;

r->next=p;

r=p;

}

return(head);

}

voidvaluelist(shnolist*L)

{

shnolist*head,*p;

intj=0;

inti;

datatypetemp,s;

head=L;

p=head->next;

temp=0;

while(j

{

p->p_sum=temp;

temp=temp+p->pb;

p->kl=-3.322*log10(p->pb)+1;

/*编码,*/

{

s=p->p_sum;

for(i=0;ikl;i++)

p->code[i]=0;

for(i=0;ikl;i++)

{

p->code[i]=2*s;

if(2*s>=1)

s=2*s-1;

elseif(2*s==0)

break;

elses=2*s;

}

}

j++;

p=p->next;

}

}

intmain(void)

{

shnolist*head;

system("cls");

pb_scan();

pb_sort();

head=my_creat(sym_arry,max_PN);

valuelist(head);

codedisp(head);

system("pause");

}

 

3.循环码的编码与译码

#include

#include

#include

 

voidmain()

{intaa[10000];

inti;

intN;

intb[4][7]={{1,0,0,0,1,0,1},{0,1,0,0,1,1,1},{0,0,1,0,1,1,0},{0,0,0,1,0,1,1}};//定义生成矩阵

inty=0,s=0;

intj,k,m;

inta[4],q[7],rr[10000/4*7];

intp,D=0;

intcc[2500],dd[2500];

inte[8][7]={{1,0,0,0,0,0,0},{0,1,0,0,0,0,0},{0,0,1,0,0,0,0},{0,0,0,1,0,0,0},{0,0,0,0,1,0,0},

{0,0,0,0,0,1,0},{0,0,0,0,0,0,1},{1,1,0,0,0,0,0}};//定义错误图样

intw[10000/4*7];

intH[7][3]={{1,0,1},{1,1,1},{1,1,0},{0,1,1},{1,0,0},{0,1,0},{0,0,1}};

intA=0,M=0,L=8;

intf[3];

intww[10000/4*7];

printf("循环码的编码与译码程序:

\n");

printf("请输入你想产生的二进制个数:

");

scanf("%d",&N);//输入想产生的信源的个数

while(N<4)

{

printf("输入无效,请重新输入");

printf("请输入你想产生的二进制个数:

");

scanf("%d",&N);

}

printf("随机产生的二进制序列为:

\n");

srand((unsigned)time(NULL));//产生一个随机序列,并把它放入a[]中

for(i=0;i

{aa[i]=rand()%2;

printf("%d",aa[i]);

}

printf("\n");

printf("编码后变为:

\n");//编码生成码字

for(m=0;m

{for(i=y;i<(y+4);i++)

{a[i-y]=aa[i];

}////取出位出来

for(j=0;j<7;j++)

{q[j]=0;

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

q[j]+=a[k]*b[k][j];/////与生成矩阵相乘

}

for(i=s;i<(s+7);i++)

{rr[i]=0;

rr[i]=q[i-s]%2;

printf("%d",rr[i]);////将生成的放入rr[]中

}

y=y+4;////向后移动位

s=s+7;///向后移动位

printf("\n");

}

printf("经过信道后变为:

\n");

srand((unsigned)time(NULL));

for(j=0;j

{cc[j]=rand()%100;////产生一个~99的随机数

if(cc[j]<9)////当随机数小于时,一个码字产生个错误

{for(i=D;i<(D+7);i++)

{w[i]=0;

w[i]=(rr[i]+e[7][i-D])%2;

printf("%d",w[i]);}

}

elseif((cc[j]>=9)&&(cc[j]<=30))///当随机数在~30时,一个码字产生一个错误

{dd[j]=rand()%7;

p=dd[j];///随机产生一个~6的数,以确定是码字一个错误的位置

for(i=D;i<(D+7);i++)

{w[i]=0;

w[i]=(rr[i]+e[p][i-D])%2;

printf("%d",w[i]);}

}

else//////当随机数在~99时,不发生错误

{for(i=D;i<(D+7);i++)

{w[i]=0;

w[i]=rr[i];

printf("%d",w[i]);}

}

D=D+7;////向后移动位

printf("%6d",cc[j]);/////进行跟踪,以确定码字

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 文化宗教

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1