信息安全基础实习报告.docx
《信息安全基础实习报告.docx》由会员分享,可在线阅读,更多相关《信息安全基础实习报告.docx(24页珍藏版)》请在冰豆网上搜索。
信息安全基础实习报告
信息安全基础实习报告
姓名:
学号:
班级:
指导老师:
1.问题描述
通信系统模型反映了各种通信系统的共同特性,对通信系统模型的研究有助于找出信息传输过程中的共同规律,以提高信息传输的可靠性、有效性、保密性和认证性。
本课题的任务是针对文本文件(txt文件)或图像文件(bmp文件)对信源编(译)码,信道编(译)码部分编程实现,并分析实验数据。
2.需求分析
该通信系统模型主要有四个模块:
信源编码(Huffman编码)、信道编码(线性分组码)、信道解码、信源解码。
信道译码结果:
文本(4.txt)
读像素:
文本(1.txt)
根据实验要求,需要读写文件,本文选择的是读取图像文件,涉及到读取图像文件的知识。
3.算法分析
3.1Huffman编码
Huffman算法是一种基于统计的压缩方法。
它的本质就是对文本文件中的字符进行重新编码,对于使用频率越高的字符,其编码也越短。
但是任何2个字符的编码,是不能出现向前包含的。
也就是说字符A的编码的前段,不可能为字符B的编码。
经过编码后的文本文件,主要包含2个部分:
Huffman码表部分和压缩内容部分。
解压缩的时候,先把Huffman码表取出来,然后对压缩内容部分各个字符进行逐一解码,形成源文件。
编码过程如下
(1)将信源符号按概率递减顺序排列;
(2)把两个最小的概率加起来,作为新符号的概率;
(3)重复步
(1)、
(2)直到概率和达到1为止;
(4)在每次合并消息时,将被合并的消息赋以1和0或0和1;
(5)寻找从每个信源符号到概率为1处的路径,记录下路径上的1和0;
(6)对每个符号写出"1"、"0"序列(从码数的根到终节点)。
哈夫曼译码过程与编码过程相反,译码过程就是分解电文中字符串的过程,具体步骤如下:
首先输入要一点问的二进制编码,然后从哈夫曼树的根结点出发,对于电文的二进制编码,按照二进制位串中的0和1确定是进入左分支还是右分支:
若编码为0,则进入结点的左孩子,否则进入结点的右孩子,一旦到达叶结点,就译出该叶子结点所代表字符。
3.2线性分组码(7,3)码
线性分组码是一类奇偶校验码,它可以由(n,k)形式表示,编码器将一个k比特信息分组(信息矢量)转变为一个更长的由给定元素符号集组成的n比特编码分组,当这个符号集包含两个元素(0和1),与二进制相对,称为二进制编码。
分组码是对每段k 位长的信息组,以一定规则增加r = n - k个检验元,组成长为n的序列:
,称这个序列为码字。
在二进制情况下,信息组总共有k2个 ,因此通过编码器后,相应的码字也有k2个,称这k2个码字集合为( n , k) 分组码。
n长序列的可能排列总共有n2种。
称被选取的k2个 n重为许用码组,其余kn22个为禁用码组,称R = k / n为码率。
那么对于(7,3)码即为用7位长的序列表示3位信息码,7位长序列的可能排列总共有128个。
许用码组有8个,其余128-8=120个禁用码组,码率为R=3/7=42.86%。
对于长度为n的二进制分组码,可以表示成(n,k),通常用于前向纠错。
在分组码中,监督位加到信息位之后,形成新码,在编码中,k个信息位,被编为n位长度,(n-k)个监督码的作用是实现检错和纠错。
⏹编码原理
(1)根据给定的生成矩阵G,求得监督码与信息码之间呈线性关系即编码方程。
(2)输入信息码,代入上述编码方程中,得到各监督码。
(3)监督码附带在信息码之后,一起输出,即得到编码结果。
已知线性分组码的生成矩阵
1001110
G=0100111
0011101
因为
[C6C5C4]G=[C6C5C4C3C2C1C0]即
1001110
[C6C5C4]0100111=[C6C5C4C3C2C1C0]
0011101
所以由上式可以得到编码方程组
C6=C6
C5=C5
C4=C4
=
+
=
+
+
=
+
=
+
表1信息码、监督码、许用码对照表
信息组
监督码
码字
000
0000
0000000
001
1101
0011101
010
0111
0100111
011
1010
0111010
100
1110
1001110
101
0011
1010011
110
1001
1101001
111
0100
1110100
⏹译码原理
(1)根据生成矩阵计算出监督矩阵H,由H计算出伴随式S。
(2)如果S=[0,0,0,0],R1无错。
(3)如果S与H的转置矩阵的某一行相等,则有一个错误,找到相应的错误图样E,则正确的接收到的码字R2=R1+E(二进制异或)。
(4)译出的码为R2的前3位。
(5)如果S不等于H转置的任意一行,则有两个或多个错误,不能得到正确的译码结果。
已知线性分组码的生成矩阵
1001110
G=0100111
0011101
G=[IkP](3)
其中Ik是k阶单位矩阵,这里k=3
1110
G=0111(4)
1101
监督矩阵H=[QIr](5)
1000
0100
Ir=0010(6)
0001
因为
P=QT(7)
所以由(4)得
101
111
Q=110(8)
011
因此由(5)(6)(8)得监督矩阵
1011000
1110100
Q=1100010(9)
0110001
4.算法实现
4.1图片处理
⏹定义结构体
//位图文件头定义;
//其中不包含文件类型信息(由于结构体的内存结构决定,
//要是加了的话将不能正确读取文件信息)
typedefstructtagBITMAPFILEHEADER
{
//WORDbfType;//文件类型,必须是0x424D,即字符“BM”
DWORDbfSize;//文件大小
WORDbfReserved1;//保留字
WORDbfReserved2;//保留字
DWORDbfOffBits;//从文件头到实际位图数据的偏移字节数
}BITMAPFILEHEADER;
typedefstructtagBITMAPINFOHEADER
{
DWORDbiSize;//信息头大小
LONGbiWidth;//图像宽度
LONGbiHeight;//图像高度
WORDbiPlanes;//位平面数,必须为1
WORDbiBitCount;//每像素位数
DWORDbiCompression;//压缩类型
DWORDbiSizeImage;//压缩图像大小字节数
LONGbiXPelsPerMeter;//水平分辨率
LONGbiYPelsPerMeter;//垂直分辨率
DWORDbiClrUsed;//位图实际用到的色彩数
DWORDbiClrImportant;//本位图中重要的色彩数
}BITMAPINFOHEADER;//位图信息头定义
typedefstructtagRGBQUAD
{
BYTErgbBlue;//该颜色的蓝色分量
BYTErgbGreen;//该颜色的绿色分量
BYTErgbRed;//该颜色的红色分量
BYTErgbReserved;//保留值
}RGBQUAD;//调色板定义
typedefstructtagIMAGEDATA//像素信息
{
BYTEblue;
//BYTEgreen;
//BYTEred;
}IMAGEDATA;
⏹像素保存
boolBMP:
:
readOfBMP()
{
cout<<"\t正在读取原文件信息,请稍后...\n"<FILE*fpi;
fpi=fopen("G:
\\学习资料\\信息安全基础实习\\ConsoleApplication1\\ConsoleApplication1\\test1.BMP","rb");
if(fpi==NULL)
{
cout<<"\t无法打开文件1!
\n"<returnfalse;
}
//判断是否是bmp格式文件
WORDbfType;
fread(&bfType,1,sizeof(WORD),fpi);
if(bfType!
=0x4d42)
{
cout<<"\t不是bmp格式的图片!
\n"<returnfalse;
}
//读取bmp文件的文件头和信息头
fread(&strHead,1,sizeof(tagBITMAPFILEHEADER),fpi);
fread(&strInfo,1,sizeof(tagBITMAPINFOHEADER),fpi);
//读取调色板
for(unsignedintnCounti=0;nCounti{
fread((char*)&(strPla[nCounti].rgbBlue),1,sizeof(BYTE),fpi);
fread((char*)&(strPla[nCounti].rgbGreen),1,sizeof(BYTE),fpi);
fread((char*)&(strPla[nCounti].rgbRed),1,sizeof(BYTE),fpi);
fread((char*)&(strPla[nCounti].rgbReserved),1,sizeof(BYTE),fpi);
}
strInfo.biWidth=(strInfo.biWidth*sizeof(IMAGEDATA)+3)/4*4;
longwidth=strInfo.biWidth;
longheight=strInfo.biHeight;
//width=(width*sizeof(IMAGEDATA)+3)/4*4;
//申请并初始化存储像素
imageDataPtr=newIMAGEDATA[width*height];
for(inti=0;i{
for(intj=0;j{
(*(imageDataPtr+i*width+j)).blue=0;
//(*(imageDataPtr+i*width+j)).green=0;
//(*(imageDataPtr+i*width+j)).red=0;
}
}
fread(imageDataPtr,sizeof(structtagIMAGEDATA)*width,height,fpi);
fclose(fpi);
cout<<"\t原文件读取完毕!
\n"<returntrue;
}
4.2Huffman解压缩
⏹Huffman树构造
构造哈夫曼树非常简单,将所有的节点放到一个队列中,用一个节点替换两个频率最低的节点,新节点的频率就是这两个节点的频率之和。
这样,新节点就是两个被替换节点的父节点了。
如此循环,直到队列中只剩一个节点(树根)。
voidHaffman(intweight[],HaffNodehaffTree[])
{
inti,j,m1,m2,x1,x2;
for(i=0;i<2*MaxN-1;i++)
{
if(i{
haffTree[i].letter=(char)i;
haffTree[i].weight=weight[i];
}
haffTree[i].flag=0;
haffTree[i].parent=-1;
haffTree[i].leftChild=-1;
haffTree[i].rightChild=-1;
}
for(i=0;i{
m1=m2=MaxValue;
x1=x2=0;
for(j=0;j{
if(haffTree[j].weight{
m2=m1;
x2=x1;
m1=haffTree[j].weight;
x1=j;
}
elseif(haffTree[j].weight{
m2=haffTree[j].weight;
x2=j;
}
}
haffTree[x1].parent=MaxN+i;
haffTree[x2].parent=MaxN+i;
haffTree[x1].flag=1;
haffTree[x2].flag=1;
haffTree[MaxN+i].weight=haffTree[x1].weight+haffTree[x2].weight;
haffTree[MaxN+i].leftChild=x1;
haffTree[MaxN+i].rightChild=x2;
}
}
⏹Huffman编码
解压缩比构造哈夫曼树要简单的多,将输入缓冲区中的每个编码用对应的ASCII码逐个替换就可以了。
只要记住,这里的输入缓冲区是一个包含每个ASCII值的编码的位流。
因此,为了用ASCII值替换编码,我们必须用位流搜索哈夫曼树,直到发现一个叶节点,然后将它的ASCII值添加到输出缓冲区中:
voidHaffmanEncode(HaffNodehaffTree[],charcode[MaxN][MaxN])//编码结果保存在2.txt文档中
{
charhcode[MaxN];
intstart,i,child,parent;
for(i=0;i{
start=MaxN-1;
hcode[--start]='\0';
child=i;
parent=haffTree[child].parent;
while(parent!
=-1)
{
if(haffTree[parent].leftChild==child)
hcode[--start]='0';
elsehcode[--start]='1';
child=parent;
parent=haffTree[child].parent;
}
strcpy(code[i],&hcode[start]);
}
}
⏹Huffman译码
voidHaffmanDecode(HaffNodehaffTree[])//译码结果保存在5.txt文档中
{
FILE*fp1,*fp2;
inti=2*MaxN-2;
charc;
if((fp1=fopen("G:
\\学习资料\\信息安全基础实习\\ConsoleApplication1\\ConsoleApplication1\\2.txt","rb"))==NULL)
{
printf("CannotOpenTheFile!
\n");
exit
(1);
}
if((fp2=fopen("G:
\\学习资料\\信息安全基础实习\\ConsoleApplication1\\ConsoleApplication1\\4.txt","wb"))==NULL)
{
printf("CannotOpenTheFile!
\n");
exit
(1);
}
fscanf(fp1,"%c",&c);
do
{
if(c=='0')i=haffTree[i].leftChild;
elsei=haffTree[i].rightChild;
if(haffTree[i].leftChild==-1)
{
fputc(haffTree[i].letter,fp2);
i=2*MaxN-2;
}
fscanf(fp1,"%c",&c);
}while(c!
='@');
fclose(fp1);
fclose(fp2);
}
4.3线性分组码
⏹线性分组码编码
voidEncode()
{
intc1[3],c2[7];
stringstr,b1;
inti=0;
FILE*fp2,*fp3;
if((fp2=fopen("G:
\\学习资料\\信息安全基础实习\\ConsoleApplication1\\ConsoleApplication1\\2.txt","r"))==NULL)
{
printf("无法打开文件!
");
exit
(1);
}
if((fp3=fopen("3.txt","w"))==NULL)
{
printf("无法打开文件!
");
exit
(1);
}
while(!
feof(fp2))
{
fscanf(fp2,"%c",&str);//将2.txt中二进制流写入str中
}
str[i]='0';
intnum=i;
num--;
for(i=0;i{
b1[i]=str[i];
if(i%3==0)
c1[0]=str[i]-'0';
elseif(i%3==1)
c1[1]=str[i]-'0';
elseif(i%3==2)
c1[2]=str[i]-'0';
if((i+1)%3==0)
{
c2[0]=c1[0];
c2[1]=c1[1];
c2[2]=c1[2];
c2[3]=c1[0]+c1[2];
c2[4]=c1[0]+c1[1]+c1[2];
c2[5]=c1[0]+c1[1];
c2[6]=c1[1]+c1[2];
for(intj=0;j<7;j++)
{
if(c2[j]==2)
c2[j]=0;
elseif(c2[j]==3)
c2[j]=1;
fprintf(fp3,"%d",c2[j]);//将线性分组码编码结果放在3.txt中
}
}
}
fclose(fp3);
}
⏹线性分组码译码
voidDecoding()
{
intG[3][7]={{1,0,0,1,1,1,0},{0,1,0,0,1,1,1},{0,0,1,1,1,0,1}};
intP[3][4],Q[4][3],HT[7][3],R2[7],C[3];
intR1[7];
intH[4][7]={0},S[4]={0},E[7]={0};
inti,j,n,k,t=0,w;
FILE*fp1,*fp2;
stringstr;
intnum;
i=0;
if((fp1=fopen("6.txt","r"))==NULL)
{
printf("无法打开文件!
");
exit
(1);
}
if((fp2=fopen("G:
\\学习资料\\信息安全基础实习\\ConsoleApplication1\\ConsoleApplication1\\4.txt","w"))==NULL)//将线性分组码的译码结果存入4.txt中
{
printf("无法打开文件!
");
exit
(1);
}
while(!
feof(fp1))
{
fscanf(fp1,"%c",&str[i++]);
}
num=i;
//printf("num=%d",num);
for(i=0;i<3;i++)
for(j=3;j<7;j++)
P[i][j-3]=G[i][j];
for(i=0;i<3;i++)
for(j=0;j<4;j++)
Q[j][i]=P[i][j];
for(i=0;i<4;i++)
for(j=0;j<3;j++)
H[i][j]=Q[i][j];
for(i=0;i<4;i++)
{
j=3;
H[i][i+j]=1;
}
for(i=0;i<4;i++)
for(j=0;j<7;j++)
HT[j][i]=H[i][j];
for(w=0;w{
if(w%7==0)
R1[0]=str[w]-'0';
elseif(w%7==1)
R1[1]=str[w]-'0';
elseif(w%7==2)
R1[2]=str[w]-'0';
elseif(w%7==3)
R1[3]=str[w]-'0';
elseif(w%7==4)
R1[4]=str[w]-'0';
elseif(w%7==5)
R1[5]=str[w]-'0';
elseif(w%7==6)
R1[6]=str[w]-'0';
intS[4]={0};
intE[7]={0};
t=0;
if((w+1)%7==0)
{
for(i=0;i<4;i++)
for(j=0;j<7;j++)
S[i]=S[i]+R