密码学实验指导
目录
实验一 凯撒密码算法实验 1 实验二 维吉利亚密码算法实验 5 实验三 普莱费尔密码算法实验 9 实验四 IDEA实验五 BCH
密码算法实验 17 纠错编码算法任务书 27
1
实验一 凯撒密码算法实验
1 实验目的
通过实验熟练掌握凯撒密码算法,学会凯撒密码算法程序设计,提高C++程序设计能力。
2 实验学时:2
实验类别:验证实验■ 3 实验环境
软件环境
Windows Xp/Windows 2000 Visual c++/Turbo c++ 3.0
硬件系统
Pentium 4 3.0G 512MRAM 计算机等
综合性实验□
设计性实验□
4 算法原理
按照a~z依次对应0~25编码,变量K存放密钥-正整数。变量M存放一明文字符ASCII码,变量C存放M中的数据经加密后得到的一密文字符的ASCII码。
加密算法:C≡(M+K)mod 26,如此继续下去,实现逐个字符进行加密。
5 实验步骤与内容
1) 编写程序 2) 编辑录入
3) 记录调试及进行情况 4) 程序结构说明文档 5) 程序使用说明文档
6 思考密钥K的有效的最小取值范围 7 实验总结与体会
8 要求提交完整的实验报告 9 参考程序代码
#include //获取密钥函数getKey() 1 int getKey() { } //将明文中的字符全部转化为大写的函数change() void change(char s[]) { } //判断输入的明文格式是否有误的函数getError() //有误则返回0,否则就返回1 int getError(char s[]) { int i,error; for(i=0;i error = 1; 2 int key; cout<<\"请输入密钥:\"; cin>>key; return key; int i; for(i=0;i s[i] = s[i]-32; } } } else { } error = 0; break; return error; //将明文转化为密文的函数getCode void getCode(char s[],char ss[],int key) { } void main() 3 int i,j; cout<<\"译出的密文:\"; for(i = 0;i if(ss[i]==s[j]) { } cout< change(incode); getCode(ss,incode,key); gets(incode); if(getError(incode)==0) { } cout<<\"您的输入有误!请重新输入!\\n\"; exit(1); int i,key,asc=65; for(i = 0;i<26;i++) { } key = getKey(); cout<<\"请输入密文:\\n\"; getchar('\\n'); ss[i] = asc++; char ss[26],incode[1000]; 4 实验二 维吉利亚密码算法实验 1 实验目的 通过实验熟练掌握维吉利亚密码算法,学会维吉利亚密码算法程序设计,提高C++程序设计能力。 2 实验学时:2 实验类别:验证实验■ 3 实验环境 软件环境 Windows Xp/Windows 2000 Visual c++/Turbo c++ 3.0 硬件系统 Pentium 4 3.0G 512MRAM 计算机等 综合性实验□ 设计性实验□ 4 算法原理 按照a~z依次对应0~25编码,数组K密钥字符串的ASCII码,数组M存放一组明文字符串ASCII码,且length(M)=length(K)=n,数组C存放M中的数据经加密后得到的一组密文字符串的ASCII码。 加密算法:C(i)≡(M(i)+K(i))mod 26 (i=1,2,……,n) 5 实验步骤与内容 1) 编写程序 2) 编辑录入 3) 记录调试及进行情况 4) 程序结构说明文档 5)程序使用说明文档 6 实验总结与体会 7 要求提交完整的实验报告 8 参考程序代码 //Vigenere.cpp文件源代码 #include 5 //将字符串小写变为大写 void change(char s[]) { } void makeCode(char incode[],char ss[],char key[],int intkey[]) { for(int i = 0;i if((i+1)%strlen(key)==0) { 6 int i; for(i=0;i s[i] = s[i]-32; cout<<\"译出的密文为:\"; //逐个比较 if(incode[i]==ss[j]) { } //逐个输出密文 cout< } } cout<<\" \"; void main() { char ss[26]; int i,j; //按照A~Z(大写)依次对应存储在char数组ss[] for(i = 0;i<26;i++) { } char select; ss[i] = i+65; do{ 7 char incode[1000]; cout<<\"请输入明文:\"; cin>>incode; //将明文小写变为大写 change(incode); char key[100]; int intkey[100]; cout<<\"请输入密钥:\"; cin>>key; //将密钥小写变为大写 change(key); //将密钥对应的下标存放在数组intkey[]中 for(i = 0;i } } 8 实验三 普莱费尔密码算法实验 1 实验目的 通过实验熟练掌握普莱费尔密码算法,学会普莱费尔码算法程序设计,提高C++程序设计能力。 2 实验学时:4 实验类别:验证实验■ 3 实验环境 软件环境 Windows Xp/Windows 2000 Visual c++/Turbo c++ 3.0 硬件系统 Pentium 4 3.0G 512MRAM 计算机等 综合性实验□ 设计性实验□ 4 算法原理 将明文中的双字母组合作为一个单元对待,并将这些单元转换为密文双字母组合。Playfair密码基于一个5*5字母矩阵,该矩阵使用一个关键词(密钥)来构造,其构造方法是:从左至右,从上至下依次填入关键词的字母(去除重复的字母),然后再以字母表顺序依次填入其他的字母。字母I和J被算作一个字母(即J被当作I处理)。对每一对明文字母p1,p2的加密方法如下。 (1) 若p1,p2在同一行时,则对应的密文c1,c2分别是仅靠p1,p2右端的字 母。其中第一行被看做是最后一行的右方(解密时反向)。 (2) 若p1,p2在同一列时,则对应的密文c1,c2分别是仅靠p1,p2下方的字 母。其中第一列被看做是最后一列的下方(解密时反向)。 (3) 若p1,p2既不在同一行,也不在同一列时,则c1,c2是由p1和p2确定的 矩 形的其他两角的字母,并且c1和p1,c2和p2同行(解密时处理方法相同)。 (4) 若p1=p2,则插入一个字母(比如Q,需要事先约定)于重复字母之间,并用 前述方法处理。 (5) 若明文字母数为奇数时,则在明文的末端添加某个事先约定的字母作为填充。 5 实验步骤与内容 1) 编写程序 2) 编辑录入 9 3) 记录调试及进行情况 4)程序结构说明文档 5)程序使用说明文档 6 实验总结与体会 7 要求提交完整的实验报告 8 参考程序代码 #include //寻找字符'J' int foundj(string s) { for(int i=0;i } } //将字符串小写变为大写 void change(char s[]) { int i; for(i=0;i s[i] = s[i]-32; 10 } } //去掉密钥中重复的字符 void dele(char key[],string codekey) { int flagk; for(int i = 1;i }if(flagk ==0) codekey+=key[i]; } for(i = 0;i } 11 //寻找字符a对应的行下标和列下标 void search(char a,int &i1,int &j1,char cod[5][5]){ } //加密矩阵 void juzhen(string codekey,char cod[][5],int m) { } //加密算法 string jiami(string codestr,char cod[5][5]){ int i; 12 int i,j; for(i=0;i<5;i++){ } for(j=0;j<5;j++) if(a==cod[i][j]) { } i1=i; j1=j; for(int i=0;i cod[i][j]=codekey[i*5+j]; for(i=0;i for(i=0;i //处于不同的行列,取对角 if(i1!=i2&&j1!=j2) { } //处于同一行,取行紧靠的数据 if(i1==i2&&j1!=j2) { } //处于同列,取列紧靠的数据 if(i1!=i2&&j1==j2) { } pt[i]=cod[(i1+1)%5][j2]; pt[i+1]=cod[(i2+1)%5][j1]; pt[i]=cod[i1][(j1+1)%5]; pt[i+1]=cod[i2][(j2+1)%5]; pt[i]=cod[i1][j2]; pt[i+1]=cod[i2][j1]; i=i+2; } return pt; 13 } void main() { cout<<\"--------------普莱费尔密码加密-------------\"< dele(key,codekey);//删除相同字符 char code[26]; for(int i=0;i //key赋给codekey for(i = 0;i code[i] = i+65; //codekey连接code for(i = 0;i<26;i++) codekey +=code[i]; 14 //key赋给key1 for(i=0;i key1[i] = key[i]; //排序key1 for(i=0;i char t = key1[i]; key1[i] = key1[j]; key1[j] = t; //删除key1中相同字符 for(i=0;i for(j=key1[i]-65-k;j } code[26-strlen(key1)] = '\\0'; codekey = key; codekey+=code; //处理i和j for(i=foundj(codekey);i //加密矩阵 char cod[5][5]; cout<<\"加密矩阵为:\"< for(i=0;i str[i] = str[i]-32; //加密 codstr=jiami(str,cod); cout<<\"对应的密文为:---->>\"< 实验四 IDEA密码算法实验 1 实验目的 通过实验熟练掌握IDEA密码算法,学会IDEA算法程序设计,提高C++程序设计能力。 2 实验学时:4 实验类别:验证实验■ 综合性实验□ 3 实验环境 软件环境 Windows Xp/Windows 2000 Visual c++/Turbo c++ 3.0 硬件系统 Pentium 4 3.0G 512MRAM 计算机等 设计性实验□ 4 算法原理 64比特的数据块分成4个子块X1,X2,X3和X4,每一个子块16比特,作为第1轮的输入,全部共8轮迭代。运算步骤如下: (1) X1和第1个子密钥块作乘法运算。 (2) X2和第2个子密钥块作加法运算。 (3) X3和第3个子密钥块作加法运算。 (4) X4和第4个子密钥块作乘法运算。 (5) (1)和(3)结果作异或运算。 (6) (2)和(4)结果作异或运算。 (7) (5)的结果与第5个子密钥块作乘法运算。 (8) (6)和(7)结果作加法运算。 (9) (8)的结果与第6个子密钥块作乘法运算。 (10) (7)和(9) 结果作加法运算。 (11) (1)和(9)结果作异或运算。 (12) (3)和(9) 结果作异或运算。 (13) (2)和(10) 结果作异或运算。 (14) (4)和(10) 结果作异或运算。结果的输出为(11),(13),(12),(14)。 除最后一轮(第8轮)外,第2和第3块交换。第8轮结束后,最后输出的变换有: 17 (1) X1和第1个子密钥块作乘法运算。 (2) X2和第2个子密钥块作加法运算。 (3) X3和第3个子密钥块作加法运算。 (4) X4和第4个子密钥块作乘法运算。 子密钥块每轮6个,最后输出变换4个,共52个。首先将128比特的密钥分成8个子密钥,每个子密钥16比特。这8个子密钥正好是第1轮的6个及第2轮的前两个。再将密钥左旋25比特,再将它分成8个子密钥。前4个是第2轮的子密钥,后4个是第3轮子密钥。将密钥再左旋25比特,产生后8个子密钥。依此类推,直到算法结束。 设密钥kk1k2k128分成8段,依次为 Z1(1)k1k2k16, (1)Z2k17k18k32, …… (1)Z6k81k82k96, Z1(2)k97k98k112, (2)Z2k113k114k128 再将k向左旋移位25比特 k26k27k128k1k2k25 (2)(2)(2)(2)分8段,前4段是第2轮的子密钥Z3,Z4,Z5,Z6;后4段依次是Z1(3),(3)(3)(3),Z3,Z4。继续以上步骤,直到52个子密钥生成完毕。 Z25 实验步骤与内容 4) 编写程序 5) 编辑录入 6) 记录调试及进行情况 4)程序结构说明文档 5)程序使用说明文档 6 实验总结与体会 18 7 要求提交完整的实验报告 8 参考程序代码 #include //将对应的字符转化为对应的二进制ASCII码 void change_ASCII(string key1,int int_key[][8]) { } // 第一次处理密钥 void z1_code(int int_key[][8],int code[][16],int m) { for(int i = 0;i < m; i++) { for(int j = 0;j < 16; j++) { 19 for(int i = 0;i < key1.length();i++) { for(int j = 0;j < 8;j++) { int_key[i][j] = key1[i]%2; key1[i] = key1[i]/2; } } cout< if(j<8) { code[i][j] = int_key[i*2][j]; }else code[i][j] = int_key[i*2+1][j-8]; } cout< cout< void change_ASCII1(long x,int s[][16],int n,int m) { 20 int temp; for(int i = 0 ; i < m ; i++) { } for(int j = 0 ; j < 16/2 ; j++) { } temp = code[i][j]; code[i][j] = code[i][15-j]; code[i][15-j] = temp; } for( int i = 0 ; i < n ; i++) { } for( i = 0 ; i < n ; i++) cout< void result1(int x[][16],int z[][16],int s[][16],int m,int n,int k) { } 21 long w1,w2,xx1 = 0 , zz1 = 0; for(int i = 0 ; i < 16 ; i++) { } if(x[m][i]!=0) xx1 = xx1 + pow(2,15-i); for( i = 0 ; i < 16 ; i++) { } if(z[n][i]!=0) zz1 = zz1 + pow(2,15-i); w1 = zz1*xx1; w2 = pow(2,16)+1; change_ASCII1(w1%w2,s,16,k); // 加法运算 void result2(int x[][16],int z[][16],int s[][16],int m,int n,int k) { int w1,w2,xx1 = 0 , zz1 = 0; for(int i = 0 ; i < 16 ; i++) { if(x[m][i]!=0) xx1 = xx1 + pow(2,15-i); } for( i = 0 ; i < 16 ; i++) { if(z[n][i]!=0) zz1 = zz1 + pow(2,15-i); } w1 = zz1+xx1; w2 = pow(2,16); change_ASCII1(w1%w2,s,16,k); } // 二进制异或 void result3(int s[][16],int m,int n,int k) { for(int i = 0 ; i < 16 ; i++) { if(s[m][i] == s[n][i]) s[k][i] = 0; else s[k][i] = 1; 22 } } cout< void sun_code(int s[][16],int z[][16]) { cout<<\"第\"< 23 static n1 = 2; int str[128]; if(n1 < 6) { } for(int i = 0,j=25 ; i < 128-25 ,j < 128; i++,j++) str[i] = s[j/16][j%16]; for(int k = 0 ; k < 16 ; k++) z[n1-2][k] = s[n1-2][k]; for(i = 0 ; i < 25 ; i++) str[i+128-25] = s[i/16][i%16]; for(i = 0 ; i < 8 ; i++) for(int j = 0 ; j < 16 ; j++) s[i][j] = str[i*16+j]; for(int j = 0 ; j < 16 ; j++) cout< // 主函数 void main() { change_ASCII(m_code1,int_code); cout< int s[14][16]; int z2[4][16]; int int_key[16][8]; //------------------------------密钥的处理----------------------------------------- string key; cout<<\"请输入密钥:\"; cin>>key; cout<<\"-------------------------->>密钥\"< cout<<\"-------------------------->>明文\"< for(int i=0;i<8;i++) { cout<<\"第\"<result2(x1,z1,s, 1,1,1); cout< //---------------------------- cout<<\"明文:\"< //-------------------------------密钥的转化---------------------------------------- int z1[8][16]; cout<<\"第1轮密钥:\"< do_code(z1,8); cout<<\"最终结果:\"< 26 实验五 BCH纠错编码算法任务书 一 实验目的 通过实验熟练掌握BCH纠错编码算法,学会BCH纠错编码算法程序设计,提高C++程序设计能力。 二 实验学时:4 实验类别:验证实验□ 三 实验环境 软件环境 Windows Xp/Windows 2000 Visual c++/Turbo c++ 3.0 硬件系统 Pentium 4 3.0G 512MRAM 计算机等 综合性实验□ 设计性实验■ 四 实验内容 1. 算法原理: (一)编码矩阵和校验矩阵: 对(n,l)编码系统,当n6,l3时,构造编码矩阵G和校验矩阵H使得: (1)G能对三位明文m(m1,m2,m3)作用后得到一个6位的发送字w,即 wmG,发送字w的后三位为校验位。 (2) 将发送字w发送后,收方的接受字为r,若r中仅有一位错,校验矩阵H能校 验 出哪位错并可予以纠错。 构造校验矩阵H的理论依据为:(nl)n的校验矩阵能正确纠正一位错误的充要条 件是H的各列为不相同的非零向量。 G(E|A) E为ll的矩阵,则G为ln的矩阵; H(A|_E) _E为(nl)(nl)矩阵,A为A的转置,H为(nl)n矩阵; rwe e是误差; HrH(we)HwHeHe '''''''27 若He0,可由He看出究竟第几位出错并给予纠正。 (二)纠错算法: (1)计算SHr; (2)若S0,则可认为传输过程是正确的,则明文mr1r2r3 (m是l长的明文 序列),若S0,转(3); (3)若S是矩阵H的第i列则认为ri有错误,予以纠正,然后取前面的l位作为明文; 若S不是矩阵H的列向量(且不为零),则认为传输过程至少出现两位以上的错 误,无法正确纠错。 '''2. 流程图: 五 实验任务 1. 2. 3. 4. 5. 编码BCH纠错编码程序 编辑录入 记录调试及运行情况 编写程序结构说明文档 编写程序使用说明文档 六 实验讨论 七 密码学设计性实验收获与总结 八 参考文献 附录:源程序代码 28 因篇幅问题不能全部显示,请点此查看更多更全内容{ }}
// 乘法运算// 子密钥得产生cout<