您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > C语言课程设计实习报告封面
信息安全基础课程设计姓名:范相地学号:20111004304专业:192112班学号:192112—28院(系):信息安全指导教师:宋军、杨帆、余林琛2014年3月第一部分数学基础与密码学部分实验内容第一章信息安全数学基础实验部分1、题目:使用VC++编程语言编写一个可测定不超过1,000,000的素数判定程序。2、定理:设n是一个正整数,如果对所有的素数p≤,都有płn,则n一定是素数。注:古希腊数学家埃拉托斯散(Eratosthenes,公元前275—公元前194)发明了求比某给定数小的素数的筛法技巧。方法如下:对于任意给定的正整数N,要求出所有不超过sqrt(N)的素数。我们列出N个整数,从中删除小于等于的所有素数p1,…,pk的倍数。然后依次删除,p1的倍数:2p1,…,p1……pk的倍数:2pk,…,pk余下的整数(不包括1)就是所要求的不超过N的素数。3、代码设计:首先要求出sqrt(n)以内的素数,创建一个函数进行调用来判断是否为素数。intis_Prime(intq){intsq;intflag=1;inti;sq=sqrt(q);for(i=2;i=sq;i++){if(q%i==0){flag=0;break;}}returnflag;}当求出sqrt(n)以内的素数,并存储于数组a[i]中,则对于要判定的素数n,只需判断是否n%a[i]==0。for(i=0;ij;i++){if(n%a[i]==0){coutn不是素数endl;break;}}if(i==j)coutn是素数endl;4、源码:#includeiostream#includemath.husingnamespacestd;intmain(){intn,k;inti;intj=0;intp=0;inta[200];cout输入数n=;cinn;intis_Prime(int);k=sqrt(n);///////////////////////////////////////////////////////for(i=2;i=k;i++){if(is_Prime(i)==1){couti;a[j]=i;j++;}}coutendlendl;////////////////////////////////////////////////////////////for(i=0;ij;i++){if(n%a[i]==0){coutn不是素数endl;break;}}if(i==j)coutn是素数endl;coutendlendl;return0;}////////////////////////////////////////////intis_Prime(intq){intsq;intflag=1;inti;sq=sqrt(q);for(i=2;i=sq;i++){if(q%i==0){flag=0;break;}}returnflag;}第二章密码学基础实验部分题目:1999年3月22日第二次AES会议上,将候选算法名单减少为5个,这5个算法是RC6,Rijndael,SERPENT,Twofish和MARS。使用VC++编程语言编写一个程序:(五选一)以Rijndael为例关于Rijndael算法:Rijndael算法首先是一个密钥分组加密的算法,通过置换(permutations)和替换(substitutions)迭代加密,进过多轮操作形成密文。AES算是Rijndael算法的一种特殊实现,选的分组为128bit(16字节),密钥可以使用128、192和256bit三种。分组上面已经说了AES分组为16个字节,下面说说他的排列,其实就是一个4x4的矩阵,不过要注意是竖着排的。AES原文:a1a2a3a4a5a6a7a8a9a10a11a12a13a14a15a16...a1a5a9a13a2a6a10a14a3a7a11a15a4a8a12a16密钥AES的密钥虽然有三种,但是并不意味着这三种密钥的AES差异很大,相反加密过程其实完全一样,只是种子密钥是128,192,256bit三种而已。密钥在AES与分组数据并没有做非常复杂的变化,其实只是简单的&(与)操作而已。不过又因为AES算法有很多轮,所有单单的种子密钥是不够的,所有AES有自己的扩展密钥的方法。还要提一下,密钥扩展后也是竖着排成方阵的。key:k1k2k3k4k5k6k7k8k9k10k11k12k13k14k15k16...k1k5k9k13k2k6k10k14k3k7k11k15k4k8k12k16轮数轮数主要跟种子密钥长度有关。一般习惯用Nk表示密钥所含的数据字数,一字表示32bit,也就是4字节,也就是一竖排。128,192,256bit对应Nk=4,6,8一般习惯用Nr表示轮数Nr=Nk+6也就是10,12,14密钥扩展(KeyExpansion)对与密钥扩展其实只要关心两点:一是扩展成多长,这个其实跟加密过程有关,暂时只要知道密钥总长度为(分组大小=16个字节)*(Nr+1),也就是4*(Nr+1)字,下面讲过程的时候就会明白为什么要这么长。二是密钥扩展的算法,密钥的算法其实比较复杂,但是却不难理解。注:Nk密钥字数,字为4字节也就是一竖排。算法步骤如下:Nk≤6的密钥扩展1)最前面的Nk个字是由种子密钥填充的。2)之后的每一个字W[j]等于前面的字W[j-1]的与Nk个位置之前的字W[j-Nk]的异或。3)而且对于Nk的整数倍的位置处的字,在异或之前,对W[j-1]的进行如下变换:.字节的循环移位RotByte-即当输入字为(a,b,c,d)时,输出字为(b,c,d,a).用S盒进行变换次位元组.异或轮常数Rcon[i/Nk]伪代码KeyExpansion(byteKey[4*Nk],W[Nb*(Nr+1)]){for(i=0;iNk;i++)W[i]=(Key[4*i],Key[4*i+1],Key[4*i+2],Key[4*i+3]);//扩展密钥的前面4个字由种子密钥组成for(i=Nk;iNb*(Nr+1);i++){temp=W[i-1];if(i%Nk==0)temp=SubByte(RotByte(temp))^Rcon[i/Nk];//i是NK的整数倍是要特殊处理W[i]=W[i-Nk]^temp;}}Nk6的密钥扩展KeyExpansion(byteKey[4*Nk],W[Nb*(Nr+1)]){for(i=0;iNk;i++)W[i]=(Key[4*i],Key[4*i+1],Key[4*i+2],Key[4*i+3]);//扩展密钥的前面4个字由种子密钥组成for(i=Nk;iNb*(Nr+1);i++){temp=W[i-1];if(i%Nk==0)temp=SubByte(RotByte(temp))^Rcon[i/Nk];//i是NK的整数倍是要特殊处理elseif(i%Nk==4)temp=SubByte(temp);//i是4的整数倍是要特殊处理W[i]=W[i-Nk]^temp;}异或轮常数Rcon[i/Nk]:Rcon[i/Nk]=(RC[i/Nk]],’00’,’00’,’00’)(i一定会大于Nk)RC[1]=‘01’RC[x]=2⊙RC[x-1]RC[1]=(01,00,00,00),RC[2]=(02,00,00,00),RC[3]=(04,00,00,00),RC[4]=(08,00,00,00),RC[5]=(10,00,00,00),RC[6]=(20,00,00,00),RC[7]=(40,00,00,00),RC[8]=(80,00,00,00),RC[9]=(1b,00,00,00),RC[10]=(36,00,00,00))每一轮分组(源数据)都要经过4种变换,分别是ByteSubShiftRowMixColumnAddRoundKeyByteSub(字节代换)这个比较简单,就是查表替代。对于分组的16字节都进行字节代换就行,还有字节一般写成16进制的也就是如FF这种。sbox如下图:ShiftRow(行移位)对于分组4x4有4行,进行如下规则位移第0行不移位,第1行左移1字节,第2行左移2字节,第3行左移3字节。MixColumn(列混合)列混合其实比较难理解。原理是数学矩阵相乘,如下图s为原数据,s‘为加密后数据。不过这里的乘法和加法都是数学域操作,说白了就是一种新的运算。加法a+b=a^b加法就是做两者的异或操作乘法0x01*b=b0x02*b只要b小于0x80,b1。如果b大于或等于0x80,(b1)^0x1b对于大于0x02可以分解成0x02和0x01的算法,这牵扯到数学域GF(2^8),可以分解成2的幂次方,在这不多做介绍,其实是本文作者能力有限,讲不清楚。b*0x03=b*(0x02+0x01)=(b*0x02)+(b*0x01)b*0x0d=b*(0x08+0x04+0x01)=(b*0x08)+(b*0x04)+(b*0x01)=(b*0x02*0x02*0x02)+(b*0x02*0x02)+(b*0x01)b*0x09=b*(0x08+0x01)=(b*0x02*0x02*0x02)+(b*0x01)b*0x0b=b*(0x08+0x02+0x01)=(b*0x02*0x02*0x02)+(b*0x02)+(b*0x01)b*0x0e=b*(0x08+0x04+0x02)=(b*0x02*0x02*0x02)+(b*0x02*0x02)+(b*0x02)AddRoundKey就是4x4的原数据与4x4的扩展密钥做异或运算下面是加密流程的伪代码,到此aes算法就介绍完了Encryption(State,CipherKey){KeyExpansion(CipherKey,RoundKey)AddRoundKey(State,RoundKey)//第0轮只做AddRoundKeyFor(i=1;iNr;i++)Round(State,RoundKey){ByteSub(State);ShiftRow(State);MixColumn(State);AddRoundKey(State,RoundKey)}FinalRound(State,RoundKey)//最后一轮不做mixcolumn{ByteSub(State);ShiftRow(State);AddRoundKey(State,RoundKey);}}第二部分信息论基础实验部分题目一算术编码1﹑题目要求算术编码是把一个信源表示为实轴上0和1之间的一个区间,信源集合中的每一个元素都用来缩短这个区间。算法流程2.设计其算法的主要算法基本思想:首先就是构造一个结构体用于存储信源的相关信息(包括信源符号,信源概率,编码的上下限);接着就是初始化信源的相关信息,如初始化编码间隔;利用算术编码的原理构造编码方法,最后实现编码3.调试分析:此算法主要就是算术编码方法的构造,初始化以后,根据初始化间隔完成编码序列的编码。在调试的过程中经常遇到一些小问题,通过一步步的调试以及修改,问题一个的解决了。同时也遇到比较大的问题,就是编码方法过程的实现,最大的体会就是必须深入理解次编码方法的原理。4.流程图开始输入信源符号及其概率(1)输入信源符号个数,信源概率分布,还有需要编码的符号序列,(2)根据概率可以算出初始编码间隔,High——当前编码的上限,Low——当前编码的下限,high——中间变量,用来计算下一个编码符号的当前间隔的上限,low——中间变量,用来计算下一个编码符号的当前间隔的下限,d——当前间隔之间的距离。(3)扫描需编码的符号序列,确定编码空间第1个编码符号的当前间隔为其初始的编码间隔,第i个编码符号的当前间隔为第i-1个编码后的[Low,High),第i+1个编码符号的当前间隔算法如下:high=
本文标题:C语言课程设计实习报告封面
链接地址:https://www.777doc.com/doc-3180446 .html