C语言实现文件的des加解密实例
DES加密解密纯C语言实现

#include<stdio.h>#include<stdlib.h>#include<string.h>void show1() //主界面{printf("\n\n\n\t\t*************** DES加密解密系统******************\n\n");printf("\t\t--------------------------------------------------\n");//printf("\t\t--------------------------------------------------\n");printf("\t\t**************************************************\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t\t1.加密\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t\t2.解密\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t\t3.退出\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t--------------------------------------------------\n");}void show2() //加密界面{printf("\n\n\n\t\t****************** DES加密**********************\n\n");printf("\t\t--------------------------------------------------\n");printf("\t\t**************************************************\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t请选择明文和密钥的输入方式:\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t1.直接输入\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t2.从文件读取\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t3.退出\t\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t--------------------------------------------------\n");printf("\t\t\t选择:");}void reader(char str[30],char s[8]) //读取明文和密钥{FILE *fp;fp=fopen(str,"r");if(fp==NULL){printf("明文读取失败!\n");}else{fscanf(fp,"%s",s);}fclose(fp);}void To2Bin(char p[8],int b[64]) //将字节转换成二进制流{int i,k=0;for(i=0;i<8;i++){int j=0x80;for(;j;j>>=1){if(j&p[i]){b[k++]=1;}else{b[k++]=0;}}}}int IP_Table[64] = //初始置换(IP){57, 49, 41, 33, 25, 17, 9, 1,59, 51, 43, 35, 27, 19, 11, 3,61, 53, 45, 37, 29, 21, 13, 5,63, 55, 47, 39, 31, 23, 15, 7,56, 48, 40, 32, 24, 16, 8, 0,58, 50, 42, 34, 26, 18, 10, 2,60, 52, 44, 36, 28, 20, 12, 4,62, 54, 46, 38, 30, 22, 14, 6};int E_Table[] = { //扩展变换E31, 0, 1, 2, 3, 4,3, 4, 5, 6, 7, 8,7, 8, 9, 10, 11, 12,11, 12, 13, 14, 15, 16,15, 16, 17, 18, 19, 20,19, 20, 21, 22, 23, 24,23, 24, 25, 26, 27, 28,27, 28, 29, 30, 31, 0};int S_Box[8][4][16] = { //8个s盒{{14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7},{ 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8},{ 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0},{15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13}},{{15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10},{ 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5},{ 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15},{13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9}},{{10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8},{13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1},{13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7},{ 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12}},{{ 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15},{13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9},{10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4},{ 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14}},{{ 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9},{14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6},{4, 2, 1, 11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14},{11,8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3}},{{12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11},{10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8},{ 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6},{ 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13}},{{ 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1},{13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6},{ 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2},{ 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12}},{{13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7},{ 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2},{ 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8},{ 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11}}};int IP_1_Table[64] = //逆初始置换IP^-1 {39, 7, 47, 15, 55, 23, 63, 31,38, 6, 46, 14, 54, 22, 62, 30,37, 5, 45, 13, 53, 21, 61, 29,36, 4, 44, 12, 52, 20, 60, 28,35, 3, 43, 11, 51, 19, 59, 27,34, 2, 42, 10, 50, 18, 58, 26,33, 1, 41, 9, 49, 17, 57, 25,32, 0, 40, 8, 48, 16, 56, 24};int P_Table[32] = //置换运算P{15,6,19,20,28,11,27,16,0,14,22,25,4,17,30,9,1,7,23,13,31,26,2,8,18,12,29,5,21,10,3,24};int PC_1[56] ={56,48,40,32,24,16,8, //密钥置换PC_10,57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43,35,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,60,52,44,36,28,20,12,4,27,19,11,3};int PC_2[48] = //密钥置换PC_2{13,16,10,23,0,4,2,27,14,5,20,9,22,18,11,3,25,7,15,6,26,19,12,1,40,51,30,36,46,54,29,39,50,44,32,47,43,48,38,55,33,52,45,41,49,35,28,31};void Replacement(int arry1[],int arry2[],int arry3[],int num) //置换函数(初始IP,逆初始IP,{int i,tmp;for(i=0;i<num;i++){tmp=arry2[i];arry3[i]=arry1[tmp];}}int move_times[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; //对左移位的规定void lif_move(int arry1[],int arry2[],int n) //左移位实现函数{int i;for(i=0;i<28;i++){arry2[i]=arry1[(n+i)%28];}}int K[16][48]; //存放16轮子密钥int c[64]; //存放明文或密文int L[17][32],R[17][32]; //存放加密过程中左右部分void SubKey(int K0[64]) //子密钥产生函数{int i;int K1[56],K2[56];int C[17][28],D[17][28];Replacement(K0,PC_1,K1,56); //密钥置换PC_1for(i=0;i<28;i++) //将PC_1输出的56比特分为左右两部分{C[0][i]=K1[i];D[0][i]=K1[i+28];}i=0;while(i<16){int j;lif_move(C[i],C[i+1],move_times[i]);lif_move(D[i],D[i+1],move_times[i]);for(j=0;j<28;j++){K2[j]=C[i+1][j];K2[j+28]=D[i+1][j];}Replacement(K2,PC_2,K[i],48); //密钥置换PC_2i++;}/*printf("\n子密钥生成过程中,左边生成的值:");for(i=0;i<17;i++){int j;printf("\nC[%d]:",i);for(j=0;j<28;j++){if(j%7==0){printf(" ");}printf("%d",C[i][j]);}}printf("\n子密钥生成过程中,右边生成的值:");for(i=0;i<17;i++){int j;printf("\nD[%d]:",i);for(j=0;j<28;j++){if(j%7==0){printf(" ");}printf("%d",D[i][j]);}}*/}void S_compress(int arry[],int shc[]) //S盒压缩变换,其中数组shc存放经过s盒的结果{int h,l; //行,列int sha[8]; //存放经过s盒的十进制结果int i,j;int temp[4];for(i=0;i<8;i++) //s盒压缩变换{h=arry[(1+(i*6))-1]*2 + arry[(6+(i*6))-1];l =arry[(2+(i*6))-1]*8 + arry[(3+(i*6))-1]*4 + arry[(4+(i*6))-1]*2 + arry[(5+(i*6))-1];sha[i]=S_Box[i][h][l];}for(i=0;i<8;i++){for(j=3;j>=0;j--){sha[i]=sha[i]/2;}for(j=0;j<4;j++){shc[4*i+j]=temp[j];}}/*printf("\n第%d次s盒的输出:",m++);for(i=0;i<32;i++){if(i%8==0){printf(" ");}printf("%d",shc[i]);}*/}void To10(int a[], int b[],int n)//二进制转十进制{int i,j;int temp;int arry[16][4];for(i=0;i<n/4;i++){for(j=0;j<4;j++){arry[i][j]=a[4*i+j];}}for (i=0;i<n/4;i++){temp=arry[i][0]*8+arry[i][1]*4+arry[i][2]*2+arry[i][3]*1;/*for(j=3;j>=0;j--){if(arry[i][j]==1){t=1;for(k=0;k<3-j;k++){t=t*2;}}}*/b[i]=temp;}}void To102(int a[], int b[],int n)//二进制转十进制{int i,j;int temp;int arry[8][8];int t=1,k;for(i=0;i<n/8;i++){for(j=0;j<8;j++){arry[i][j]=a[8*i+j];}}for (i=0;i<n/8;i++){temp=0;for(j=7;j>=0;j--){if(arry[i][j]==1){t=1;for(k=0;k<7-j;k++){t=t*2;}temp+=t;}}b[i]=temp;}}void F_Function(int a[32],int b[32],int n) //F函数{int i;int tmp[48];int tep[32];Replacement(a,E_Table,tmp,48); //扩展变换E /*printf("\n第%d轮E盒扩展结果:",n);for(i=0;i<48;i++){if(i%8==0)printf(" ");printf("%d",tmp[i]);}*/for(i=0;i<48;i++) //与子密钥异或{tmp[i] ^= K[n][i];}/*printf("\n进入S盒的48比特:");for(i=0;i<48;i++){if(i%6==0){printf(" ");}printf("%d",tmp[i]);}*/S_compress(tmp,tep); //压缩变换SReplacement(tep,P_Table,b,32); //置换运算P/*printf("\n第%d次P置盒输出:",l++);for(i=0;i<32;i++){if(i%8==0)printf(" ");printf("%d",b[i]);}*//*printf("\nf[%d]的输出结果:",n);for(i=0;i<32;i++){if(i%8==0){printf(" ");}printf("%d",b[i]);}*/}void Encryption(int m0[64],int c1[64]){int i,k;int arry[32];int c0[64],m1[64];Replacement(m0,IP_Table,m1,64); //初始置换IP/*printf("\n初始置换:");for(i=0;i<64;i++){if(i%8==0)printf(" ");printf("%d",m1[i]);}*/for(i=0;i<32;i++){L[0][i]=m1[i];R[0][i]=m1[i+32];}k=1;while(k<17){F_Function(R[k-1],arry,k-1);for(i=0;i<32;i++){L[k][i]=R[k-1][i];R[k][i]=L[k-1][i]^arry[i];}k++;}for(i=0;i<32;i++){c0[i]=R[16][i];c0[i+32]=L[16][i];}Replacement(c0,IP_1_Table,c1,64); //逆初始置换}void changeKey(int a[16][48]){int i,j;int tmp[16][48];for(i=0;i<16;i++)for(j=0;j<48;j++){tmp[i][j]=a[i][j];}}for(i=0;i<16;i++){for(j=0;j<48;j++){K[i][j]=tmp[15-i][j];}}}void Decryption(int c1[],int m[]){int c0[64],t[64];int i,k;int arry[32];changeKey(K);/*printf("\n交换后的密钥:\n");for(i=0;i<16;i++){printf("\n");for(j=0;j<48;j++){if(j%8==0){printf(" ");}printf("%d",K[i][j]);}}*/Replacement(c1,IP_Table,c0,64); //初始IP for(i=0;i<32;i++){L[0][i]=c0[i];R[0][i]=c0[i+32];}k=1;while(k<17)F_Function(R[k-1],arry,k-1);for(i=0;i<32;i++){L[k][i]=R[k-1][i];R[k][i]=L[k-1][i]^arry[i];}k++;}for(i=0;i<32;i++){t[i]=R[16][i];t[i+32]=L[16][i];}Replacement(t,IP_1_Table,m,64); //逆初始置换}void print() //输出函数{int i;int a[12],b[12],d[3][16];int p[64],q[64];for(i=0;i<32;i++){p[i]=L[15][i];p[32+i]=R[15][i];q[i]=R[16][i];q[i+32]=L[16][i];}To10(K[14],a,48);To10(K[15],b,48);To10(c,d[0],64);To10(p,d[1],64);To10(q,d[2],64);printf("\n\t\t15轮密钥:");for(i=0;i<12;i++){printf("%x",a[i]);}printf("\t15轮结果:");for(i=0;i<16;i++){printf("%X",d[1][i]);printf("\n\t\t16轮密钥:");for(i=0;i<12;i++){printf("%X",b[i]);}printf("\t16轮结果:");for(i=0;i<16;i++){printf("%X",d[2][i]);}printf("\n\t\t最后结果:");for(i=0;i<16;i++){printf("%X",d[0][i]);}/*printf("\n最后结果二进制:");for(i=0;i<64;i++){printf("%d",c[i]);}*/}int main(){int num,i,t;char s1[8],s2[8];int m[64]; //m存放二进制明文/密文int d[64]; //存放二进制密钥int s[8];show1();printf("\t\tinput you choice:");while(1){scanf("%d",&num);switch(num){case 1:system("cls"); //调用清屏函数show2();{scanf("%d",&num);if(num==1){while(strlen(s1)!=8){printf("\t\t请输入明文(8):");scanf("%s",s1);}To2Bin(s1,m); //将明文转换成二进制流while(strlen(s2)!=8){printf("\t\t请输入密钥(8):");scanf("%s",s2);}To2Bin(s2,d); //将密钥转换成二进制/*printf("\n初始二进制明文:");for(i=0;i<64;i++){printf("%d",m[i]);}*//*printf("\n初始二进制密钥:");for(i=0;i<64;i++){printf("%d",d[i]);}*/SubKey(d);/*printf("\n16轮子密钥如下:");for(i=0;i<16;i++){printf("\nK[%d]:",i+1);for(j=0;j<48;j++){if(j%8==0)printf(" ");printf("%d",K[i][j]);}}*/Encryption(m,c);/*printf("\n16次迭代左结果:");for(i=0;i<17;i++){printf("\nL[%d]:",i);for(j=0;j<32;j++){if(j%8==0){printf(" ");}printf("%d",L[i][j]);}}printf("\n16次迭代右结果:");for(i=0;i<17;i++){printf("\nR[%d]:",i);for(j=0;j<32;j++){if(j%8==0){printf(" ");}printf("%d",R[i][j]);}}*/print();/*printf("\n二进制密文:");for(i=0;i<64;i++){printf("%d",c[i]);}*/printf("\n\t\t按0将此密文解密,1返回上一层,2返回主界面,其他键退出.....");scanf("%d",&t);if(t==0){int s[8];int a[64];Decryption(c,a);/*printf("\n解密后的二进制:");for(i=0;i<64;i++){printf("%d",a[i]);}*/To102(a,s,64);printf("\n\t\t解密结果:");for(i=0;i<8;i++){printf("%c",s[i]);}printf("\n\t\t按1加密,2解密,3退出");}else if(t==1){system("cls");show2();}else if(t==2){system("cls");show1();}else{exit(0);}}else if(num==2){char str1[20],str2[20];printf("\t\t请输入明文文件名:");scanf("%s",str1);reader(str1,s1);To2Bin(s1,m);printf("\t\t请输入密钥文件名:");scanf("%s",str2);reader(str2,s2);To2Bin(s2,d);SubKey(d);Encryption(m,c);print();printf("\n\t\t按0将此密文解密,1将密文存入文件,2返回主界面,其他键退出.....");scanf("%d",&t);if(t==0){int a[64];Decryption(c,a);/*printf("\n解密后的二进制:");for(i=0;i<64;i++){printf("%d",a[i]);}*/To102(a,s,64);printf("\n\t\t解密结果:");for(i=0;i<8;i++){printf("%c",s[i]);}printf("\n\t\t按1加密,2解密,3退出");}else if(t==1){int a[16];char str[30];FILE *fw;printf("\n\t\t请输入文件名:");scanf("%s",str);fw=fopen(str,"w");if(fw==NULL){printf("\n\t\t文件打开失败!\n");}else{To10(c,a,64);for(i=0;i<16;i++){fprintf(fw,"%X",a[i]);}}fclose(fw);printf("\n\t\t密文保存成功!按1加密,2解密,3退出");}else if(t==2){system("cls");show1();}else{exit(0);}}else if(num==3){system("cls");exit(0);}else{printf("\n\t\t输入不正确,请重新输入:");}}break;case 2:{system("cls");printf("\n\n\t\t------------------DES解密----------------");while(strlen(s1)!=8){printf("\n\n\n\t\t请输入密文(8):");scanf("%s",s1);}To2Bin(s1,m);while(strlen(s2)!=8){printf("\t\t请输入密钥(8):");scanf("%s",s2);}To2Bin(s2,d);SubKey(d);Decryption(m,c);print();printf("\n\t\t按1返回上一层,2返回主界面,其他键退出.....");scanf("%d",&t);if(t==1){system("cls");printf("\n\n\t\t---------------DES解密-------------");while(strlen(s1)!=8){printf("\n\n\t\t请输入密文(8):");scanf("%s",s1);}To2Bin(s1,m);while(strlen(s2)!=8){printf("\t\t请输入密钥(8):");scanf("%s",s);}To2Bin(s2,d);SubKey(d);Decryption(m,c);print();}else if(t==2){system("cls");show1();}else{exit(0);}}break;case 3:system("cls");exit(0);default:printf("输入不正确,请重新输入:");}}return 0;}说明:程序中有大部分的注释代码,去掉注释可查看各部分中间结果,如:十六轮子密钥,十六轮结果等程序运行主界面:加密界面:运行结果一:运行结果二:。
DES加密算法与解密(带流程图)

DES加密算法与解密(带流程图)一、DES加密及解密算法程序源代码:#include <iostream>using namespace std;const static char IP_Table[] = { //IP_Table置换58, 50, 42, 34, 26, 18, 10, 2,60, 52, 44, 36, 28, 20, 12, 4,62, 54, 46, 38, 30, 22, 14, 6,64, 56, 48, 40, 32, 24, 16, 8,57, 49, 41, 33, 25, 17, 9, 1,59, 51, 43, 35, 27, 19, 11, 3,61, 53, 45, 37, 29, 21, 13, 5,63, 55, 47, 39, 31, 23, 15, 7};const static char Final_Table[] = { //最终置换40, 8, 48, 16, 56, 24, 64, 32,39, 7, 47, 15, 55, 23, 63, 31,38, 6, 46, 14, 54, 22, 62, 30,37, 5, 45, 13, 53, 21, 61, 29,36, 4, 44, 12, 52, 20, 60, 28,35, 3, 43, 11, 51, 19, 59, 27,34, 2, 42, 10, 50, 18, 58, 26,33, 1, 41, 9, 49, 17, 57, 25};const static char S_Box[8][64] = {//s_box/* S1 */{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},/* S2 */{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10,14, 5, 2, 8, 4,3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},/* S5 */{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},/* S6 */{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},/* S7 */{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},/* S8 */{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}const static char Rar_Table[] = { //压缩置换14, 17, 11, 24, 1, 5,3, 28, 15, 6, 21, 10,23, 19, 12, 4, 26, 8,16, 7, 27, 20, 13, 2,41, 52, 31, 37, 47, 55,30, 40, 51, 45, 33, 48,44, 49, 39, 56, 34, 53,46, 42, 50, 36, 29, 32};const static char Exp_Table[] = { //扩展置换32, 1, 2, 3, 4, 5,4, 5, 6, 7, 8, 9,8, 9, 10, 11, 12, 13,12, 13, 14, 15, 16, 17,16, 17, 18, 19, 20, 21,20, 21, 22, 23, 24, 25,24, 25, 26, 27, 28, 29,28, 29, 30, 31, 32, 1const static char P_Table[]={ //P置换16, 7, 20, 21,29, 12, 28, 17,1, 15, 23, 26,5, 18, 31, 10,2, 8, 24, 14,32, 27, 3, 9,19, 13, 30, 6,22, 11, 4, 25};const static char KeyRar_Table[]={57, 49, 41, 33, 25, 17, 9,1, 58, 50, 42, 34, 26, 18,10, 2, 59, 51, 43, 35, 27,19, 11, 3, 60, 52, 44, 36,63, 55, 47, 39, 31, 23, 15,7, 62, 54, 46, 38, 30, 22,14, 6, 61, 53, 45, 37, 29,21, 13, 5, 28, 20, 12, 4};//设置全局变量,16轮密钥bool key[16][48]={{0}};void ByteToBit(bool *Out,char *In,int bits) //字节到位转换函数{int i;for(i=0;i<bits;i++)Out[i]=(In[i/8]>>(i%8))&1;}void BitToByte(char *Out,bool *In,int bits)//位到字节转换函数{int i;for(i=0;i<bits/8;i++)Out[i]=0;for(i=0;i<bits;i++)Out[i/8]|=In[i]<<(i%8);}void Xor(bool *InA,const bool *InB,int length) //按位异或for(int i=0;i<length;i++)InA[i]^=InB[i];}void keyfc(char *In) //密钥生成函数{int i,j=0,mov,k,m;bool* key0 = new bool[56];bool* keyin = new bool[64];bool temp;ByteToBit(keyin,In,64); //字节到位的转换for(i=0;i<56;i++) //密钥压缩为56位key0[i]=keyin[KeyRar_Table[i]-1];for(i=0;i<16;i++) //16轮密钥产生{if(i==0||i==1||i==8||i==15)mov=1;elsemov=2;for(k=0;k<mov;k++) //分左右两块循环左移{for(m=0;m<8;m++){temp=key0[m*7];for(j=m*7;j<m*7+7;j++)key0[j]=key0[j+1];key0[m*7+6]=temp;}temp=key0[0];for(m=0;m<27;m++)key0[m]=key0[m+1];key0[27]=temp;temp=key0[28];for(m=28;m<55;m++)key0[m]=key0[m+1];key0[55]=temp;}for(j=0;j<48;j++) //压缩置换并储存key[i][j]=key0[Rar_Table[j]-1];}delete[] key0;delete[] keyin;}void DES(char Out[8],char In[8],bool Type)//加密核心程序,Type=0时加密,反之解密{bool* MW = new bool[64];bool* tmp = new bool[32];bool* PMW = new bool[64];bool* kzmw = new bool[48];bool* keytem = new bool[48];bool* ss = new bool[32];int hang,lie,i;ByteToBit(PMW,In,64);for(int j=0;j<64;j++){MW[j]=PMW[IP_Table[j]-1]; //初始置换}bool *Li=&MW[0],*Ri=&MW[32];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];if(Type==0) //DES加密过程{for(int lun=0;lun<16;lun++){for(i=0;i<32;i++)ss[i]=Ri[i];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];for(i=0;i<48;i++)keytem[i]=key[lun][i];Xor(kzmw,keytem,48);/*S盒置换*/for(i=0;i<8;i++)hang=kzmw[i*6]*2+kzmw[i*6+5];lie=kzmw[i*6+1]*8+kzmw[i*6+2]*4+kzmw[i*6+3] *2+kzmw[i*6+4];tmp[i*4+3]=S_Box[i][(hang+1)*16+lie]%2;tmp[i*4+2]=(S_Box[i][(hang+1)*16+lie]/2)%2 ;tmp[i*4+1]=(S_Box[i][(hang+1)*16+lie]/4)%2 ;tmp[i*4]=(S_Box[i][(hang+1)*16+lie]/8)%2;}for(i=0;i<32;i++) //P置换Ri[i]=tmp[P_Table[i]-1];Xor(Ri,Li,32); //异或for(i=0;i<32;i++) //交换左右明文Li[i]=ss[i];}}for(i=0;i<32;i++){tmp[i]=Li[i];Li[i]=Ri[i];Ri[i]=tmp[i];}for(i=0;i<64;i++)PMW[i]=MW[Final_Table[i]-1];BitToByte(Out,PMW,64); //位到字节的转换}else //DES解密过程{for(int lun=15;lun>=0;lun--){for(i=0;i<32;i++)ss[i]=Ri[i];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];for(i=0;i<48;i++)keytem[i]=key[lun][i];Xor(kzmw,keytem,48);/*S盒置换*/for(i=0;i<8;i++){hang=kzmw[i*6]*2+kzmw[i*6+5];lie=kzmw[i*6+1]*8+kzmw[i*6+2]*4+kzmw[i*6+3] *2+kzmw[i*6+4];tmp[i*4+3]=S_Box[i][(hang+1)*16+lie]%2;tmp[i*4+2]=(S_Box[i][(hang+1)*16+lie]/2)%2 ;tmp[i*4+1]=(S_Box[i][(hang+1)*16+lie]/4)%2 ;tmp[i*4]=(S_Box[i][(hang+1)*16+lie]/8)%2; }for(i=0;i<32;i++) //P置换Ri[i]=tmp[P_Table[i]-1];Xor(Ri,Li,32); //异或for(i=0;i<32;i++) //交换左右明文{Li[i]=ss[i];}}for(i=0;i<32;i++){tmp[i]=Li[i];Li[i]=Ri[i];Ri[i]=tmp[i];}for(i=0;i<64;i++)PMW[i]=MW[Final_Table[i]-1]; BitToByte(Out,PMW,64); //位到字节的转换}delete[] MW;delete[] tmp;delete[] PMW;delete[] kzmw;delete[] keytem;delete[] ss;}bool RunDes(char *Out, char *In, int datalength, char *Key, bool Type) //加密运行函数,判断输入以及对输入文本8字节分割{if( !( Out && In && Key && (datalength=(datalength+7)&0xfffffff8) ) ) return false;keyfc(Key);for(int i=0,j=datalength%8; i<j; ++i,Out+=8,In+=8)DES(Out, In, Type);return true;}int main(){char* Ki = new char[8];char Enter[]="This is the test of DES!"; char* Print = new char[200];int len = sizeof(Enter);int i_mf;cout << "请输入密钥(8位):" <<"\n"; for(i_mf=0;i_mf<8;i_mf++)cin >> Ki[i_mf];cout << "\n";RunDes(Print,Enter,len,Ki,0);//加密cout << "----加密前----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout << Enter[i_mf];cout << "\n\n";cout << "----加密后----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout<<Print[i_mf];cout << "\n\n";//此处进行不同密钥输入测试cout << "请输入密钥(8位):" <<"\n"; for(i_mf=0;i_mf<8;i_mf++)cin >> Ki[i_mf];cout << "\n";RunDes(Enter,Print,len,Ki,1);//解密cout << "----解密后----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout << Enter[i_mf];cout << endl;delete[] Ki;delete[] Print;return 0;}二、程序编译、运行结果图:三、程序总体框架图:读取待加密文本输入密钥DES 加密显示加密后文本再次输入密钥DES 解密显示解密后文本显示错误解密信息密钥错误密钥正确四、程序实现流程图:Enter = 待加密文本分割Enter ,8字节为一段,不足补加,段数为N 初始化:*Print ,i=0,j=0文本第i 段,转为二进制64位初始置换(IP_Table )文本段分为左右两部分左部分(32位)右部分(32)输入8字节密钥转为二进制64位密钥压缩KeyRar_Table (56位)形成16轮密钥合并形成子密钥(48位)S 置换(S_Box )P 置换(P_Table )左右交换,j++最终置换(Final_Table )J<16扩展置换(Exp_Table )i<N异或异或NoYes存入*Print ,i++DES 加密过程结束,输出Print YesNoDES 解密过程为以上逆过程。
DES算法的C语言实现

DES算法的C语⾔实现利⽤C语⾔实现DES算法,分组密码原理过程很简单,但是在写的过程中检查了好久才发现错误原因,主要有两点:1.在加密过程16轮迭代过程中,最后⼀轮迭代运算后的结果并没有进⾏交换,即C=IP-1(R16,L16),这样做的⽬的是为了加密解密使⽤同⼀个算法2.在S盒的过程中,移位后应该加括号,否则+的优先级⾼于<<,会出错,下⾯是算法源码:1 #include "des.h"2 #include <stdio.h>3 #include <stdlib.h>45const unsigned char IP_table[64] = {658, 50, 42, 34, 26, 18, 10, 2,760, 52, 44, 36, 28, 20, 12, 4,862, 54, 46, 38, 30, 22, 14, 6,964, 56, 48, 40, 32, 24, 16, 8,1057, 49, 41, 33, 25, 17, 9, 1,1159, 51, 43, 35, 27, 19, 11, 3,1261, 53, 45, 37, 29, 21, 13, 5,1363, 55, 47, 39, 31, 23, 15, 714 };1516const unsigned char IPR_table[64] = {1740, 8, 48, 16, 56, 24, 64, 32,1839, 7, 47, 15, 55, 23, 63, 31,1938, 6, 46, 14, 54, 22, 62, 30,2037, 5, 45, 13, 53, 21, 61, 29,2136, 4, 44, 12, 52, 20, 60, 28,2235, 3, 43, 11, 51, 19, 59, 27,2334, 2, 42, 10, 50, 18, 58, 26,2433, 1, 41, 9, 49, 17, 57, 2525 };2627const unsigned char E_table[48] = {2832, 1, 2, 3, 4, 5,294, 5, 6, 7, 8, 9,308, 9, 10, 11, 12, 13,3112, 13, 14, 15, 16, 17,3216, 17, 18, 19, 20, 21,3320, 21, 22, 23, 24, 25,3424, 25, 26, 27, 28, 29,3528, 29, 30, 31, 32, 136 };3738const unsigned char P_table[32] = {3916, 7, 20, 21, 29, 12, 28, 17,401, 15, 23, 26, 5, 18, 31, 10,412, 8, 24, 14, 32, 27, 3, 9,4219, 13, 30, 6, 22, 11, 4, 2543 };4445const unsigned char PC1_table[56] = {4657, 49, 41, 33, 25, 17, 9,471, 58, 50, 42, 34, 26, 18,4810, 2, 59, 51, 43, 35, 27,4919, 11, 3, 60, 52, 44, 36,5063, 55, 47, 39, 31, 23, 15,517, 62, 54, 46, 38, 30, 22,5214, 6, 61, 53, 45, 37, 29,5321, 13, 5, 28, 20, 12, 454 };5556const unsigned char LOOP_table[16] = {571, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 158 };5960const unsigned char PC2_table[48] = {6114, 17, 11, 24, 1, 5,623, 28, 15, 6, 21, 10,6323, 19, 12, 4, 26, 8,6416, 7, 27, 20, 13, 2,6541, 52, 31, 37, 47, 55,6630, 40, 51, 45, 33, 48,6744, 49, 39, 56, 34, 53,6846, 42, 50, 36, 29, 3269 };7071const unsigned char sbox[8][4][16] = {72// S17314, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,740, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,754, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,7615, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,77//S27815, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,793, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,800, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,8113, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,82//S38310, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,8413, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,8513, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,861, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,87//S4887, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,8913, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,9010, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,913, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,92//S5932, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,9414, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,954, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,9611, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,97//S69812, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,9910, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,1009, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,1014, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,102//S71034, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,10413, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,1051, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,1066, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,107//S810813, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,1091, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,1107, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,1112, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11112 };113114void ByteToBit(unsigned char* out, const unsigned char* in, const int bits){115for(int i=0;i<bits;i++)116out[i]=(in[i/8]>>(7-i%8))&1;117 }118119void BitToByte(unsigned char* out, const unsigned char* in, const int bits){120 memset(out, 0, (bits + 7) / 8);121for(int i=0;i<bits;i++)122out[i/8]|=in[i]<<(7-i%8);123 }124125void Transform(unsigned char* out,const unsigned char* in, const unsigned char* table, const int len){ 126 unsigned char tmp[64] = {0};127for (int i = 0; i < len; i++)128 tmp[i] = in[table[i] - 1];129 memcpy(out, tmp, len);130 }131132void RotateL(unsigned char* in, const int len, int loop){133static unsigned char tmp[64];134 memcpy(tmp, in, len);135 memcpy(in, in + loop, len - loop);136 memcpy(in + len - loop, tmp, loop);137 }138139static unsigned char subKey[16][48] = { 0 };140void setKey(const unsigned char* in){141char key[64] = { 0 };142 ByteToBit(key, in, 64);143char temp[56]={0};144 Transform(temp, key, PC1_table, 56);145for(int i=0;i<16;i++){146 RotateL(temp, 28, LOOP_table[i]);147 RotateL(temp + 28, 28, LOOP_table[i]);148 Transform(subKey[i], temp, PC2_table, 48);149 }150 }151152void xor(unsigned char* in1,const unsigned char* in2,int len){153for(int i=0;i<len;i++)154 in1[i]^=in2[i];155 }156157void sbox_exchange(unsigned char* out,const unsigned char* in){158char row, column;159for (int i = 0; i < 8; i++){160char num = 0;161 row = (in[6 * i]<<1)+ in[6 * i + 5];162 column = (in[6 * i + 1] << 3) + (in[6 * i + 2] << 2) + (in[6 * i + 3] << 1) + in[6 * i + 4]; 163 num = sbox[i][row][column];164for (int j = 0; j < 4; j++)165 {166out[4 * i + j] = (num >> (3 - j)) & 1;167 }168 }169 }170171void F_func(unsigned char* out,const unsigned char* in,unsigned char* subKey){172 unsigned char temp[48]={0};173 unsigned char res[32]={0};174 Transform(temp, in, E_table, 48);175 xor(temp,subKey,48);176 sbox_exchange(res,temp);177 Transform(out, res, P_table, 32);178 }179180void encryptDES(unsigned char* out,const unsigned char* in, const unsigned char* key){ 181 unsigned char input[64] = { 0 };182 unsigned char output[64] = { 0 };183 unsigned char tmp[64] = { 0 };184 ByteToBit(input, in, 64);185 Transform(tmp, input, IP_table, 64);186char* Li = &tmp[0], *Ri = &tmp[32];187 setKey(key);188for(int i=0;i<16;i++){189char temp[32]={0};190 memcpy(temp,Ri,32);191 F_func(Ri, Ri,subKey[i]);192 xor(Ri, Li, 32);193 memcpy(Li,temp,32);194 }195 RotateL(tmp, 64, 32);//the input is LR,output is RL196 Transform(output, tmp, IPR_table, 64);197 BitToByte(out, output,64);198 }199200void decryptDES(unsigned char* out,const unsigned char* in, const unsigned char* key){ 201 unsigned char input[64] = { 0 };202 unsigned char output[64] = { 0 };203 unsigned char tmp[64] = { 0 };204 ByteToBit(input, in, 64);205 Transform(tmp, input, IP_table, 64);206char* Li = &tmp[0], *Ri = &tmp[32];207 setKey(key);208 RotateL(tmp, 64, 32);209for (int i = 0; i < 16; i++){210char temp[32] = { 0 };211 memcpy(temp, Li, 32);212 F_func(Li, Li,subKey[15 - i]);213 xor(Li, Ri, 32);214 memcpy(Ri, temp, 32);215 }216 Transform(output, tmp, IPR_table, 64);217 BitToByte(out, output, 64);218 }。
用c语言实现des算法

用c语言实现des算法由于DES算法被广泛应用于加密和数据安全方面,因此在计算机科学领域,了解和实现DES算法是非常重要的。
C语言是一种强大的编程语言,其通用性和高效性使其成为实现DES算法的理想选择。
以下是使用C语言实现DES算法的步骤和方法:1.将明文和密钥转换为二进制格式在DES算法中,明文和密钥必须先转换为二进制格式才能进行加密或解密操作。
可以使用一个字符串数组来存储明文和密钥,然后使用C 语言的位运算符将每个字符转换为二进制格式。
2.对明文进行初始置换DES算法的第一步是对明文进行初始置换。
可以使用一个int型数据来存储初始置换后的结果。
3.密钥生成使用密钥生成算法来生成16个48位的子密钥。
可以使用一个二维数组来存储每个子密钥。
4.将初始置换后的明文分为左右两个部分将初始置换后的明文分为左右两个部分,每个部分32位。
5.进行16轮迭代在每轮迭代中,右半部分32位的明文和48位的子密钥进行异或运算,然后使用S盒置换和P盒置换来处理数据。
最后将结果与左半部分32位的明文异或,以更新下一轮迭代所需的数据。
6.合并左右两个部分在进行最后一轮迭代后,将左右两个部分合并成一段64位的二进制数据。
7.进行最后的逆置换使用逆置换来处理上一步生成的64位二进制数据,以生成最终的密文。
实现DES算法需要一定的数学知识和编程技能,因此建议有一定编程基础的人才尝试实现此算法。
列表:1.使用C语言实现DES算法步骤2.将明文和密钥转换为二进制格式的方法3.对明文进行初始置换的具体过程4.密钥生成算法的原理和实现方法5.如何将初始置换后的明文分为左右两个部分6.DES算法16轮迭代的详细过程7.如何合并左右两个部分的数据8.DES算法中的最后一步逆置换的作用和过程9.DES算法的应用场景和重要性10.如何使用C语言实现DES算法的具体步骤和技巧。
DES加解密算法的实例

DES加解密算法的实例DES(Data Encryption Standard)是一种对称密钥加密算法,由IBM于1977年开发。
它是最早广泛使用且被接受的加密算法之一,被用于许多领域,如金融、电子商务和电子邮件等。
DES算法的基本操作单元是64位的数据块,它使用一个56位的密钥对数据进行加密和解密。
下面将对DES算法的加密和解密过程进行详细说明。
1.密钥生成:DES算法使用的密钥是56位的,由8个字节构成。
然而,为了增强安全性和抵抗暴力破解,通常将密钥扩展为64位,即每个字节的最高位被视为奇偶校验位。
密钥生成过程将密钥扩展到64位,并生成16个子密钥。
2.初始置换(IP置换):加密过程开始前,明文数据块会被进行初始置换。
这个初始置换步骤的目的是打乱明文的比特位,使其在加密过程中更难以分析。
3. 轮函数(Feistel函数):DES算法使用了16个相同的轮函数,每个轮函数包含以下步骤:a.扩展置换(E-置换):将32位的数据扩展为48位。
b.异或操作:将扩展得到的48位数据与一个子密钥进行异或操作。
c.S-盒替换:将异或结果分为8个6位的子块,每个子块经过一个6×4的S盒代替变换。
d.P-置换:将S盒代替变换后的结果进行置换操作。
e.得到一个32位的数据。
4.加解密:加密和解密过程中,轮函数通过迭代应用于数据块。
在加密过程中,子密钥按照顺序应用于轮函数;而在解密过程中,子密钥的应用次序与加密过程相反。
DES算法采用了16轮迭代,每轮迭代后,加解密都会进行部分结果的异或操作。
5.逆初始置换(IP-1置换):在加密或解密过程的最后,最终得到的数据块需要进行逆初始置换。
这个逆初始置换的目的是撤销初始置换操作,使得结果与初始的明文或密文一致。
DES算法的实例:1.加密过程:c.将64位的密钥扩展为56位并生成子密钥。
e.经过逆初始置换,得到最终加密的密文。
2.解密过程:a.经过逆初始置换,得到初始的密文数据块。
DES对称加密算法详解和c++代码实现(带样例和详细的中间数据)

DES对称加密算法详解和c++代码实现(带样例和详细的中间数据)特点:1.DES是对称性加密算法,即加密和解密是对称的,⽤的是同⼀个密钥2.DES只处理⼆进制数据,所以需要将明⽂转换成为2进制数据3.DES每次处理64位的数据,所以应该将明⽂切割成64位的分组,当最后⼀组数据不⾜64位的时候,⾼位补04.DES使⽤64位的密钥,但因为密钥中的每8位会被忽略,所以有效的密钥长度是56位,从⽽产⽣16个48位的⼦密钥(变换过程后⾯会说明)5.每64位数据⼀个块,是DES的永恒组织⽅式具体样例分析:(仅以⼀组64位数据为例分析加密过程)明⽂M是:8787878787878787密钥K是:0E329232EA6D0D73上⾯的信息都是16进制的,转换为2进制明⽂M是:0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111密钥K是:00010011 00110100 01010111 01111001 10011011 10111100 11011111 11110001第⼀步:根据密钥⽣成16个⼦密钥1.根据密钥初始置换表将64位的密钥转化为58位的密钥57 49 41 33 25 17 91 58 50 42 34 26 1810 2 59 51 43 35 2719 11 3 60 52 44 3663 55 47 39 31 23 157 62 54 46 38 30 2214 6 61 53 45 37 2921 13 5 28 20 12 4由于上表中第⼀个元素为57,这将使原秘钥的第57位变换为新秘钥K+的第1位。
同理,原秘钥的第49位变换为新秘钥的第2位……原秘钥的第4位变换为新秘钥的最后⼀位。
注意原秘钥中只有56位会进⼊新秘钥,上表也只有56个元素。
原密钥K:00010011 00110100 01010111 01111001 10011011 10111100 11011111 11110001新密钥K:1111000 0110011 0010101 0101111 0101010 1011001 1001111 00011112.将新密钥拆分成C0和D0,每组都有28位⽐如新密钥C0:1111000 0110011 0010101 0101111D0:0101010 1011001 1001111 00011113.根据密钥轮次左移表,左移特定的位数1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 161 12 2 2 2 2 2 1 2 2 2 2 2 2 1⽐如第⼀轮是左移1位,第⼆轮也是左移1位,第三轮是左移两位所以C1:1110000110011001010101011111D1:1010101011001100111100011110下⾯给出C1,D1到C16,D16的数据:C1 = 1110000110011001010101011111D1 = 1010101011001100111100011110C2 = 1100001100110010101010111111D2 = 0101010110011001111000111101C3 = 0000110011001010101011111111D3 = 0101011001100111100011110101C4 = 0011001100101010101111111100D4 = 0101100110011110001111010101C5 = 1100110010101010111111110000D5 = 0110011001111000111101010101C6 = 0011001010101011111111000011D6 = 1001100111100011110101010101C7 = 1100101010101111111100001100D7 = 0110011110001111010101010110C8 = 0010101010111111110000110011D8 = 1001111000111101010101011001C9 = 0101010101111111100001100110D9 = 0011110001111010101010110011C10 = 0101010111111110000110011001D10 = 1111000111101010101011001100C11 = 0101011111111000011001100101D11 = 1100011110101010101100110011C12 = 0101111111100001100110010101D12 = 0001111010101010110011001111C13 = 0111111110000110011001010101D13 = 0111101010101011001100111100C14 = 1111111000011001100101010101D14 = 1110101010101100110011110001C15 = 1111100001100110010101010111D15 = 1010101010110011001111000111C16 = 1111000011001100101010101111D16 = 0101010101100110011110001111需要记住的是:每⼀对Cn 和 Dn都是由前⼀对Cn-1 和 Dn-1移位⽽来!4.得到Cn,Dn后合并CnDn,然后根据密钥压缩置换表将56位密钥压缩成48位的⼦密钥密钥压缩置换表:14 17 11 24 1 53 28 15 6 21 1023 19 12 4 26 816 7 27 20 13 241 52 31 37 47 5530 40 51 45 33 4844 49 39 56 34 5346 42 50 36 29 32每对⼦秘钥有56位,但PC-2仅仅使⽤其中的48位。
DES实验报告

DES
[实验目的] C语言实现des加密解密
[实验原理]
1.DES的加密过程: 第一阶段:初始置换IP。在第一轮迭代之前,需要加密的64位明文首先通过初始置换IP 的作用,对输 入分组实施置换。最后,按照置换顺序,DES将64位的置换结果分为左右两部分,第1位到第32位记为 L0,第33位到第64位记为R0。 第二阶段:16次迭代变换。DES采用了典型的Feistel结构,是一个乘积结构的迭代密码算法。其算法的 核心是算法所规定的16次迭代变换。DES算法的16才迭代变换具有相同的结构,每一次迭代变换都以前 一次迭代变换的结果和用户密钥扩展得到的子密钥Ki作为输入;每一次迭代变换只变换了一半数据,它 们将输入数据的右半部分经过函数f后将其输出,与输入数据的左半部分进行异或运算,并将得到的结果 作为新的有半部分,原来的有半部分变成了新的左半部分。用下面的规则来表示这一过程(假设第i次迭 代所得到的结果为LiRi): Li = Ri-1; Ri = Li-1⊕ f(Ri-1,Ki);在最后一轮左与右半部分并未变换,而是直接 将R16 L16并在一起作为未置换的输入。 第三阶段:逆(初始)置换。 他是初始置换IP的逆置换,记为IP-1。在对16次迭代的结果(R16 L16) 再使用逆置换IP-1后,得到的结果即可作为DES加密的密文Y输出,即Y = IP-1 (R16 L16)。 2.DES解密过程: DES的解密算法与其加密算法使用的算法过程相同。两者的不同之处在于解密时子密钥Ki的使用顺序与 加密时相反,如果子密钥为K1K2… K16,那么解密时子密钥的使用顺序为K16K15… K1,即使用DES解密 算法进行解密时,将以64位密文作为输入,第1次迭代运算使用子密钥K16,第2次迭代运算使用子密钥 K15,… … ,第16 次迭代使用子密钥K1,其它的运算与加密算法相同。这样,最后输出的是64位明文。
DES加解密算法C语言源代码

DES加解密算法C语言源代码以下是一个实现DES加解密算法的C语言源代码,包含了加密和解密函数。
请注意,这个代码只是为了演示DES算法的工作原理,并不是一个完整的、安全的加密算法实现。
```c#include <stdio.h>#include <stdint.h>typedef structuint8_t key[8];uint8_t subkeys[16][6];} DESKey;void generateSubkeys(uint8_t* key, uint8_t subkeys[16][6]) //略过子密钥生成算法的具体实现//这里只是假设生成的子密钥都是随机的,实际生成过程要更复杂for (int i = 0; i < 16; i++)for (int j = 0; j < 6; j++)subkeys[i][j] = (i+j) % 256;}}void DES(uint8_t* input, uint8_t key[8], uint8_t* output, int encrypt)//略过DES加密算法的具体实现DESKey desKey;for (int i = 0; i < 8; i++)desKey.key[i] = key[i];}generateSubkeys(key, desKey.subkeys);//这里只是假设输入输出是8字节长,实际上可以支持任意长度//执行加解密操作if (encrypt)printf("Encrypting: ");} elseprintf("Decrypting: ");}for (int i = 0; i < 8; i++)output[i] = encrypt ? input[i] ^ desKey.subkeys[0][i%6] : input[i] ^ desKey.subkeys[15][i%6];printf("%02X ", output[i]);}printf("\n");int maiuint8_t input[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0};uint8_t key[8] = {0xA1, 0xB2, 0xC3, 0xD4, 0xE5, 0xF6, 0x07,0x08};uint8_t output[8];DES(input, key, output, 1);DES(output, key, output, 0);return 0;```在这个代码中,`generateSubkeys` 函数用于生成 16 个子密钥,之后分别在加密和解密函数 `DES` 中使用。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C语言实现文件的des加解密实例c语言中的正则 ,d3.js画矢量图+可拖拽的实现思路 DOM2级事件处理程序跨浏览器兼容事件 ,exel导入/导出和csv文件导入、导出 ,Go http访问使用代理golang进行socket通讯 ,hessian+hibernate 懒加载处理 ,HTML+CSS代码橙色导航菜单html5 撞球游戏// get 网络请求func Get(api string,params .Values)(rs[]byte ,err error){var *.,err=.Parse(api)if err!=nil{fmt.Printf("解析错误:\r\n%v",err)return nil,err}//如果参数中有中文参数,这个方法会进行Encode//iOS KVO注册和监听方法//C语言websocket编程.RawQuery=params.Encode()resp,err:=http.Get(.String())if err!=nil{fmt.Println("err:",err)return nil,err}defer resp.Body.Close()return ioutil.ReadAll(resp.Body)}// post 网络请求 ,params 是.Values类型func Post(api string, params .Values)(rs[]byte,err error){resp,err:=http.PostForm(api, params)if err!=nil{return nil ,err}defer resp.Body.Close()return ioutil.ReadAll(resp.Body)}//代码描述:基于GO的黄金数据接口调用代码实例//关联数据:黄金数据//css之before and after[代码] [C#]代码using System;using System.Collections.Generic;using System.Linq;using System.Text;using ;using System.IO;using ;using System.Diagnostics;using System.Web;void QEditor::setCurrentFile(const QString &fileName){m_currentFileName = fileName;ui->textEdit->document()->setModified(false);}bool QEditor::maybeSave(){if (ui->textEdit->document()->isModified()) {QMessageBox::StandardButton ret;ret = QMessageBox::warning(this, tr("QEditor"),tr("The document has been modified.\n""Do you want to save your changes?"),QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);if (ret == QMessageBox::Save)return save();else if (ret == QMessageBox::Cancel)return false;}return true;}bool QEditor::savefile(const QString &fileName){QFile file(fileName);if (!file.open(QFile::WriteOnly | QFile::Text)) {QMessageBox::warning(this, tr("QEditor"),tr("Cannot write file %1:\n%2.").arg(fileName).arg(file.errorString()));return false;}QTextStream out(&file);out << ui->textEdit->toPlainText();setCurrentFile(fileName);ui->statusBar->showMessage(QString("%1 saved.").arg(fileName), 2000);return true;}[代码] [Google Go]代码package mainimport ("io/ioutil""net/http""net/""fmt""encoding/json")//----------------------------------// 黄金数据调用示例代码-聚合数据// 在线接口文档:www/docs/29//----------------------------------const APPKEY = "*******************" //您申请的APPKEYfunc main(){//1.上海黄金交易所Request1()//2.上海期货交易所Request2()//3.银行账户黄金Request3()}//1.上海黄金交易所func Request1(){//请求地址juhe :="web:8080/finance/gold/shgold"//初始化参数param:=.Values{}//配置请求参数,方法内部已处理encode问题,中文参数可以直接传参 param.Set("key",APPKEY) //APP Keyparam.Set("v","") //JSON格式版本(0或1)默认为0//发送请求data,err:=Get(juhe,param)if err!=nil{fmt.Errorf("请求失败,错误信息:\r\n%v",err)}else{var netReturn map[string]interface{}json.Unmarshal(data,&netReturn)if netReturn["error_code"].(float64)==0{fmt.Printf("接口返回result字段是:\r\n%v",netReturn["result"]) }}}//2.上海期货交易所func Request2(){//请求地址juhe :="web:8080/finance/gold/shfuture"//初始化参数param:=.Values{}//配置请求参数,方法内部已处理encode问题,中文参数可以直接传参param.Set("key",APPKEY) //APP Keyparam.Set("v","") //JSON格式版本(0或1)默认为0//发送请求data,err:=Get(juhe,param)if err!=nil{fmt.Errorf("请求失败,错误信息:\r\n%v",err)}else{var netReturn map[string]interface{}json.Unmarshal(data,&netReturn)if netReturn["error_code"].(float64)==0{fmt.Printf("接口返回result字段是:\r\n%v",netReturn["result"]) }}}//3.银行账户黄金func Request3(){//请求地址juhe :="web:8080/finance/gold/bankgold"//初始化参数param:=.Values{}//配置请求参数,方法内部已处理encode问题,中文参数可以直接传参param.Set("key",APPKEY) //APP Key//发送请求data,err:=Get(juhe,param)if err!=nil{fmt.Errorf("请求失败,错误信息:\r\n%v",err)}else{var netReturn map[string]interface{}json.Unmarshal(data,&netReturn)if netReturn["error_code"].(float64)==0{fmt.Printf("接口返回result字段是:\r\n%v",netReturn["result"]) }}}//----------------------------------// 黄金数据调用示例代码-聚合数据// 在线接口文档:www/docs/29// 代码中JsonObject类下载地址:/download/gcm3206021155665/7458439//----------------------------------namespace ConsoleAPI{class Program{static void Main(string[] args){string appkey = "*******************"; //配置您申请的appkey//1.上海黄金交易所string 1 = "web:8080/finance/gold/shgold";var parameters1 = new Dictionary<string, string>();parameters1.Add("key", appkey);//你申请的keyparameters1.Add("v" , ""); //JSON格式版本(0或1)默认为0string result1 = sendPost(1, parameters1, "get");JsonObject newObj1 = new JsonObject(result1);String errorCode1 = newObj1["error_code"].Value;if (errorCode1 == "0"){Debug.WriteLine("成功");Debug.WriteLine(newObj1);}else{//Debug.WriteLine("失败");Debug.WriteLine(newObj1["error_code"].Value+":"+newObj1["reason"].Value); }//2.上海期货交易所string 2 = "web:8080/finance/gold/shfuture";var parameters2 = new Dictionary<string, string>();parameters2.Add("key", appkey);//你申请的keyparameters2.Add("v" , ""); //JSON格式版本(0或1)默认为0string result2 = sendPost(2, parameters2, "get");JsonObject newObj2 = new JsonObject(result2);String errorCode2 = newObj2["error_code"].Value;if (errorCode2 == "0"){Debug.WriteLine("成功");Debug.WriteLine(newObj2);}else{//Debug.WriteLine("失败");Debug.WriteLine(newObj2["error_code"].Value+":"+newObj2["reason"].Value); }//3.银行账户黄金string 3 = "web:8080/finance/gold/bankgold";var parameters3 = new Dictionary<string, string>();parameters3.Add("key", appkey);//你申请的keystring result3 = sendPost(3, parameters3, "get");JsonObject newObj3 = new JsonObject(result3);String errorCode3 = newObj3["error_code"].Value;if (errorCode3 == "0"){Debug.WriteLine("成功");Debug.WriteLine(newObj3);}else{//Debug.WriteLine("失败");Debug.WriteLine(newObj3["error_code"].Value+":"+newObj3["reason"].Value);}}/// <summary>/// Http (GET/POST)/// </summary>/// <param name="">请求</param>/// <param name="parameters">请求参数</param>/// <param name="method">请求方法</param>/// <returns>响应内容</returns>static string sendPost(string , IDictionary<string, string> parameters, string method){if (method.ToLower() == "post"){HttpWebRequest req = null;HttpWebResponse rsp = null;System.IO.Stream reqStream = null;try{req = (HttpWebRequest)WebRequest.Create();req.Method = method;req.KeepAlive = false;req.ProtocolVersion = HttpVersion.Version10;req.Timeout = 5000;req.ContentType ="application/x-www-form-encoded;charset=utf-8";byte[] postData =Encoding.UTF8.GetBytes(BuildQuery(parameters, "utf8"));reqStream = req.GetRequestStream();reqStream.Write(postData, 0, postData.Length);rsp = (HttpWebResponse)req.GetResponse();Encoding encoding = Encoding.GetEncoding(rsp.CharacterSet); return GetResponseAsString(rsp, encoding);}catch (Exception ex){return ex.Message;}finally{if (reqStream != null) reqStream.Close();if (rsp != null) rsp.Close();}}else{//创建请求HttpWebRequest request = (HttpWebRequest)WebRequest.Create( + "?" + BuildQuery(parameters, "utf8"));//GET请求request.Method = "GET";request.ReadWriteTimeout = 5000;request.ContentType = "text/html;charset=UTF-8";HttpWebResponse response =(HttpWebResponse)request.GetResponse();Stream myResponseStream = response.GetResponseStream();StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));//返回内容string retString = myStreamReader.ReadToEnd();return retString;}}/// <summary>/// 组装普通文本请求参数。