DES加密算法C实现

合集下载

DES算法的c++实现

DES算法的c++实现

DES算法的c++实现⽤数组存的位,改天⽤unsigned int重写下。

依然不负责填充。

#include<stdio.h>#include<string.h>int IP_Table[64] = { //IP置换矩阵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 };int E_Table[48] = { //扩展矩阵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, 1 };int P_Table[32] = { // 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};int IPR_Table[64] = { //逆IP置换矩阵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 };int PC1_Table[56] = { //密钥第⼀次置换矩阵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 };int PC2_Table[48] = { // 密钥第⼆次置换矩阵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 };int S_Box[8][4][16]={ //8个S盒三维数组// S114, 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,// S215, 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,// S310, 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,// S47, 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,// S52, 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,// S612, 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,// S74, 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,// S813, 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};//把CHAR转换为INTstatic void CharToBit(const char input[],int output[],int bits){int i,j;for(j=0;j<8;j++){for(i=0;i<8;i++){output[8*j+7-i]=(input[j]>>i)&1;}}};//把INT转换为CHARstatic void BitToChar(const int intput[],char output[],int bits){int i,j;for(j=0;j<8;j++){for(i=0;i<8;i++){output[j]=output[j]*2+intput[i+8*j];}}};//异或操作static void Xor(int *INA,int *INB,int len){int i;for(i=0;i<len;i++){*(INA+i)=*(INA+i)^*(INB+i);}};//初始IP置换,64->64,左右分别32static void IP(const int input[64],int output[64],int table[64]){int i;for(i=0;i<64;i++){output[i]=input[table[i]-1];//减1操作不可少!!}};//E扩展32->48static void E(const int input[32],int output[48],int table[48]){int i;for(i=0;i<48;i++){output[i]=input[table[i]-1];}};//P置换,static void P(const int input[32],int output[32],int table[32]){int i;for(i=0;i<32;i++){output[i]=input[table[i]-1];}};//逆IPstatic void IP_In(const int input[64],int output[64],int table[64]){int i;for(i=0;i<64;i++){output[i]=input[table[i]-1];}};//PC_1,⽤于密钥置换static void PC_1(const int input[64],int output[56],int table[56]){int i;for(i=0;i<56;i++){output[i]=input[table[i]-1];}};//PC_2static void PC_2(const int input[56],int output[48],int table[48]){int i;for(i=0;i<48;i++){output[i]=input[table[i]-1];}};//S盒压缩static void S(const int input[48],int output[32],int table[8][4][16]){int i=0;int j=0;int INT[8];for(;i<48;i+=6){INT[j]=table[j][(input[i]<<1)+(input[i+5])][(input[i+1]<<3)+(input[i+2]<<2)+(input[i+3]<<1)+(input[i+4])]; j++;}for(j=0;j<8;j++){for(i=0;i<4;i++){output[4*j+3-i]=(INT[j]>>i)&1;}}};//完成DES算法轮变换,就是f函数的内部实现,就是⼀个异或⽽已static void F_func(int input[32],int output[32], int subkey[48]){int len=48;int temp[48]={0};int temp_1[32]={0};E(input,temp,E_Table);//32->48Xor(temp,subkey,len);S(temp,temp_1,S_Box);//48->32P(temp_1,output,P_Table);//位数不变};//秘钥循环左移static void RotateL(const int input[28],int output[28], int leftCount){int i;int len=28;//因为不是位运算,所以可以不⽤unsignedfor(i=0;i<len;i++){output[i]=input[(i+leftCount)%len];}};//⼦密钥⽣成static void subKey_fun(const int input[64],int Subkey[16][48]){//注意输⼊和输出的位数,int只存放01,密钥为18位16轮int loop=1,loop_2=2;int i,j;int c[28],d[28];int pc_1[56]={0};int pc_2[16][56]={0};int rotatel_c[16][28]={0};int rotatel_d[16][28]={0};PC_1(input,pc_1,PC1_Table);for(i=0;i<28;i++){c[i]=pc_1[i];//Ld[i]=pc_1[i+28];//R}int leftCount=0;for(i=1;i<17;i++){if(i==1||i==2||i==9||i==16){//左移⼀位leftCount+=loop;RotateL(c,rotatel_c[i-1],leftCount);RotateL(d,rotatel_d[i-1],leftCount);}else{//左移两位leftCount += loop_2;RotateL(c,rotatel_c[i-1],leftCount);RotateL(d,rotatel_d[i-1],leftCount);}}for(i=0;i<16;i++){for(j=0;j<28;j++){pc_2[i][j]=rotatel_c[i][j];pc_2[i][j+28]=rotatel_d[i][j];}}for(i=0;i<16;i++){PC_2(pc_2[i],Subkey[i],PC2_Table);}};//加密实现static void DES_Efun(char input[8],char key_in[8],int output[64]){int Ip[64]={0};//存储初始置换后的矩阵int output_1[64]={0};int subkeys[16][48];int chartobit[64]={0};int key[64];int l[17][32],r[17][32];CharToBit(input,chartobit,8);//转换为64个⼆进制数IP(chartobit,Ip,IP_Table);//IP初始置换!CharToBit(key_in,key,8);subKey_fun(key,subkeys);for(int i=0;i<32;i++){l[0][i]=Ip[i];r[0][i]=Ip[32+i];}for(int j=1;j<16;j++){//前15轮的操作for(int k=0;k<32;k++){l[j][k]=r[j-1][k];}F_func(r[j-1],r[j],subkeys[j-1]);Xor(r[j],l[j-1],32);}int t=0;for(t=0;t<32;t++){//最后⼀轮的操作,合并了将l,r swapr[16][t]=r[15][t];}F_func(r[15],l[16],subkeys[15]);Xor(l[16],l[15],32);for(t=0;t<32;t++){output_1[t]=l[16][t];output_1[32+t]=r[16][t];}IP_In(output_1,output,IPR_Table);};//解密实现static void DES_Dfun(int input[64],char key_in[8],char output[8]){ int Ip[64]={0};//存储初始置换后的矩阵int output_1[64]={0};int output_2[64]={0};int subkeys[16][48];//int chartobit[64]={0};int key[64];int l[17][32],r[17][32];IP(input,Ip,IP_Table);//IP初始置换CharToBit(key_in,key,8);subKey_fun(key,subkeys);for(int i=0;i<32;i++){l[0][i]=Ip[i];r[0][i]=Ip[32+i];}for(int j=1;j<16;j++){//前15轮的操作for(int k=0;k<32;k++){l[j][k]=r[j-1][k];}F_func(r[j-1],r[j],subkeys[16-j]);Xor(r[j],l[j-1],32);}int t=0;for(t=0;t<32;t++){//最后⼀轮的操作r[16][t]=r[15][t];}F_func(r[15],l[16],subkeys[0]);Xor(l[16],l[15],32);for(t=0;t<32;t++){output_1[t]=l[16][t];output_1[32+t]=r[16][t];}IP_In(output_1,output_2,IPR_Table);BitToChar(output_2,output,8);};int main(){int output[64]={0};char MIN[9]={0};char MI[9]={0};printf("请输⼊明⽂\n");gets(MIN);printf("请输⼊秘钥\n");gets(MI);DES_Efun(MIN,MI,output);printf("密⽂如下:\n");for(int i=0;i<64;i++){printf("%d",output[i]);if((i+1)%4==0)printf("\n");}printf("\n");printf("解密功能\n");DES_Dfun(output,MI,MIN);printf("明⽂如下:\n");for(int i=0;i<8;i++){printf("%c",MIN[i]);}printf("\n");return0;}。

DES加密算法 C++版

DES加密算法 C++版

/*** Des加密算法初步完成版* 使用基础函数实现** @version 0.9* @author alexWu* @电子邮箱:alexthinking(at)* @新浪微博:/vikingalex* @完成日期:2011-10-25**/#include <cstdlib>#include <iostream>using namespace std;//轮密钥,由轮密钥生成器getKeys(key)获得并赋值int keys[16][48];//密匙置换选择1表,调用:getKeysint keyTable11[4][7] = {{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}};int keyTable12[4][7] = {{63, 55, 47, 39, 31, 33, 15},{7, 62, 54, 46, 38, 30, 22},{14, 6, 61, 53, 45, 37, 29},{21, 13, 5, 28, 20, 12, 4}};//密匙置换选择2表,调用:getKeysint keyTable2[8][6] = {{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}};//明文初始置换,调用:encryptint displaceTable[8][8] = {{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}};//明文逆初始置换,调用:encryptint antiDisplaceTable[8][8] = {{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}};//扩展变换E,在F变换中调用:fTrans()int expandTable[8][6] = {{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, 1}};//S盒压缩,调用:sBoxTransint sBox[8][4][16] = {// 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, 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} },// S3盒{{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} },// S4盒{{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} },// 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} }};//置换变换P,调用:fTransint pTable[8][4] = {{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}};//将16进制字符串转换为二进制整形数组void HexToBin(char content[], int intArr[]) {for (int i = 0; i < 16; i++) {switch (content[i]) {case '0': intArr[i*4]=0; intArr[i*4+1]=0; intArr[i*4+2]=0; intArr[i*4+3]=0; break;case '1': intArr[i*4]=0; intArr[i*4+1]=0; intArr[i*4+2]=0; intArr[i*4+3]=1; break;case '2': intArr[i*4]=0; intArr[i*4+1]=0; intArr[i*4+2]=1; intArr[i*4+3]=0; break;case '3': intArr[i*4]=0; intArr[i*4+1]=0; intArr[i*4+2]=1; intArr[i*4+3]=1; break;case '4': intArr[i*4]=0; intArr[i*4+1]=1; intArr[i*4+2]=0; intArr[i*4+3]=0; break;case '5': intArr[i*4]=0; intArr[i*4+1]=1; intArr[i*4+2]=0; intArr[i*4+3]=1; break;case '6': intArr[i*4]=0; intArr[i*4+1]=1; intArr[i*4+2]=1; intArr[i*4+3]=0; break;case '7': intArr[i*4]=0; intArr[i*4+1]=1; intArr[i*4+2]=1; intArr[i*4+3]=1; break;case '8': intArr[i*4]=1; intArr[i*4+1]=0; intArr[i*4+2]=0; intArr[i*4+3]=0; break;case '9': intArr[i*4]=1; intArr[i*4+1]=0; intArr[i*4+2]=0; intArr[i*4+3]=1; break;case 'A': intArr[i*4]=1; intArr[i*4+1]=0; intArr[i*4+2]=1; intArr[i*4+3]=0; break;case 'B': intArr[i*4]=1; intArr[i*4+1]=0; intArr[i*4+2]=1; intArr[i*4+3]=1; break;case 'C': intArr[i*4]=1; intArr[i*4+1]=1; intArr[i*4+2]=0; intArr[i*4+3]=0; break;case 'D': intArr[i*4]=1; intArr[i*4+1]=1; intArr[i*4+2]=0; intArr[i*4+3]=1; break;case 'E': intArr[i*4]=1; intArr[i*4+1]=1; intArr[i*4+2]=1; intArr[i*4+3]=0; break;case 'F': intArr[i*4]=1; intArr[i*4+1]=1; intArr[i*4+2]=1; intArr[i*4+3]=1; break;}}}//将二进制整形数组转换为16进制字符串void BinToHex(int intArr[], char content[], int hexLen) {int tep;for (int i = 0; i < hexLen; i++) {tep = intArr[i*4]*8 + intArr[i*4+1]*4 + intArr[i*4+2]*2 + intArr[i*4+3];switch (tep) {case 0: content[i]='0'; break;case 1: content[i]='1'; break;case 2: content[i]='2'; break;case 3: content[i]='3'; break;case 4: content[i]='4'; break;case 5: content[i]='5'; break;case 6: content[i]='6'; break;case 7: content[i]='7'; break;case 8: content[i]='8'; break;case 9: content[i]='9'; break;case 10: content[i]='A'; break;case 11: content[i]='B'; break;case 12: content[i]='C'; break;case 13: content[i]='D'; break;case 14: content[i]='E'; break;case 15: content[i]='F'; break;}}if (hexLen < strlen(content)) {for (int i = hexLen; i < strlen(content); i++) {content[i]=' ';}}}//将密钥中C和D合并void plusArray(int c[], int d[], int result[], int len) {for (int i = 0; i < len; i++) {result[i] = c[i];}for (int i = 0; i < len; i++) {result[i + len] = d[i];}}//密钥置换选择1void keyTableTrans1(int binArr[64], int resultArr[28], int table[4][7]){ int count = 0;for (int i = 0; i < 4; i++) {for (int j = 0; j < 7; j++) {resultArr[count++] = binArr[table[i][j]-1];}}}//密钥置换选择2void keyTableTrans2(int binArr[56], int resultArr[16][48], int table[8][6], int index){ int count = 0;for (int i = 0; i < 8; i++) {for (int j = 0; j < 6; j++) {resultArr[index][count++] = binArr[table[i][j]-1];}}}//循环左移void leftMove(int count, int arr[]) {int arrLen = 28;int moveTable[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};if (moveTable[count] == 1) {int tep0 = arr[0];for (int i = 0; i < arrLen - 1; i++) {arr[i] = arr[i+1];}arr[arrLen-1] = tep0;} else {int tep0 = arr[0];int tep1 = arr[1];for (int i = 0; i < arrLen - 2; i++) {arr[i] = arr[i+2];}arr[arrLen-2] = tep0;arr[arrLen-1] = tep1;}}//获取轮密钥void getKeys(char key[]){cout<<"密钥:"<<key<<endl;int keyIntArr[64], C[28], D[28];//将16进制字符串转换为二进制整形数组HexToBin(key, keyIntArr);//依次输出64位的二进制数组密钥//for (int i = 0; i < 64; i++) {// cout<<keyIntArr[i];//}//cout<<endl;//密钥置换选择1keyTableTrans1(keyIntArr, C, keyTable11);keyTableTrans1(keyIntArr, D, keyTable12);int tepKeyArr[56];//密钥C和D合并的暂存数组int tepKeyRstArr[48];//置换选择2后的48位数组char keysStr[12];//密钥转换的16进制字符串for (int i = 0; i < 16; i++) {leftMove(i, C);leftMove(i, D);//密钥C和D合并plusArray(C, D, tepKeyArr, 28);keyTableTrans2(tepKeyArr, keys, keyTable2, i);//依次输出置换选择2后的48位的二进制数组密钥//for (int j = 0; j < 48; j++) {// cout<<keys[i][j];//}//cout<<endl;//将二维数组keys的行key[i]赋给一维数组tepKeyRstArr//以便转换为16进制字符串for (int j = 0; j < 48; j++) {tepKeyRstArr[j] = keys[i][j];}BinToHex(tepKeyRstArr, keysStr, 12);cout<<"K"<<i+1<<" : "<<keysStr<<endl;}}//明文初始置换void plaintextTableTrans(int binArr[64], int table[8][8]){int tepBinary[64];int count = 0;for (int i = 0; i < 8; i++) {for (int j = 0; j < 8; j++) {tepBinary[count++] = binArr[table[i][j]-1];}}memcpy(binArr, tepBinary, sizeof(int) * 64);}//扩展运算Evoid expandTableTrans(int binArr[64], int resultArr[48], int table[8][6]){int count = 0;for (int i = 0; i < 8; i++) {for (int j = 0; j < 6; j++) {resultArr[count++] = binArr[table[i][j]-1];}}}//置换运算Pvoid pTableTrans(int binArr[32], int table[8][4]){int tepBinary[32];int count = 0;for (int i = 0; i < 8; i++) {for (int j = 0; j < 4; j++) {tepBinary[count++] = binArr[table[i][j]-1];}}memcpy(binArr, tepBinary, sizeof(int) * 32);}//复制数组void arrCopy(int sourceArray[], int result[], int startIndex) { //已知要复制数组长度为32for (int i = 0; i < 32; i++) {result[i] = sourceArray[startIndex + i];}}//数组每个元素异或运算void arrayXOR(int array1[], int array2[], int len) {for (int i = 0; i <len ; i++) {array1[i] = array1[i] ^ array2[i];}}//将S盒中取出的1-15的十进制数字转换为2进制4位整型数组void DecToBin(int intArr4[], int result) {intArr4[0] = result/8;intArr4[1] = (result%8)/4;intArr4[2] = (result%8%4)/2;intArr4[3] = result%8%4%2;}//选择压缩变换,S盒代替void sBoxTrans(int resultArr[], int arr[]) {int result = 0;int intArr4[4];int j = 0;for (int i = 0; i < 8; i++, j = i*6) {//获取S盒中对应的数据result = sBox[i][arr[j]*2 + arr[j+5]][arr[j+1]*8 + arr[j+2]*4 + arr[j+3]*2 + arr[j+4]];//将S盒中取出的十进制数转化成二进制DecToBin(intArr4, result);for (int n = 0, m = i*4; n < 4; n++) {resultArr[m+n] = intArr4[n];;}}}//F变换void fTrans(int R[], int index) {//F变换中的扩展运算Eint tepR[48];expandTableTrans(R, tepR, expandTable);//将二维数组keys的行key[i]赋给一维数组tepKeyArrint key[48];for (int j = 0; j < 48; j++) {key[j] = keys[index][j];}//扩展运算的得到的tepR与轮密匙key进行异或运算arrayXOR(tepR, key, 48);//选择压缩变换,S盒代替int sBoxArr[32];sBoxTrans(sBoxArr, tepR);//置换运算PpTableTrans(sBoxArr, pTable);memcpy(R, sBoxArr, sizeof(int) * 32);}//迭代处理void loop(int arr[]) {int L[32],R[32];arrCopy(arr, L, 0);arrCopy(arr, R, 32);char LStr[9]=" ",RStr[9]=" ";//先定义好L和RBinToHex(L, LStr, 8);BinToHex(R, RStr, 8);cout<<"L0:"<<LStr<<endl;cout<<"R0:"<<RStr<<endl;int tep[32];//前15轮乘积变换for (int i = 0; i < 15; i++) {memcpy(tep, R, sizeof(int) * 32);fTrans(R, i);//F变换arrayXOR(R, L, 32);//异或运算,得到最后的Rmemcpy(L, tep, sizeof(int) * 32);BinToHex(L, LStr, 8);BinToHex(R, RStr, 8);cout<<"L"<<i+1<<":"<<LStr<<" ";cout<<"R"<<i+1<<":"<<RStr<<endl;}//最后一轮乘积变换memcpy(tep, R, sizeof(int) * 32);fTrans(R, 15);//F变换arrayXOR(L, R, 32);//异或运算,得到最后的Rmemcpy(R, tep, sizeof(int) * 32);BinToHex(L, LStr, 8);BinToHex(R, RStr, 8);cout<<"L16:"<<LStr<<" ";cout<<"R16:"<<RStr<<endl;plusArray(L, R, arr, 32);}//加密void encrypt(char plaintext[]) {int binary[64];//二进制整型明文数组//将16进制表示的字符串转换为二进制字符串HexToBin(plaintext, binary);//初始置换plaintextTableTrans(binary, displaceTable);//16轮乘积变换loop(binary);//逆初始置换plaintextTableTrans(binary, antiDisplaceTable);BinToHex(binary, plaintext, 16);cout<<"密文:"<<plaintext<<endl;}//主函数int main(){char test[17]= "123456ABCD132536";//测试所用明文cout<<"明文:"<<test<<endl; //输出明文getKeys("AABB09182736CCDD");//获取密钥encrypt(test);//加密system("PAUSE");return 0;}。

DES算法的C语言实现

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算法

用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对称加密算法详解和c++代码实现(带样例和详细的中间数据)

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加解密算法C语言源代码

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` 中使用。

C语言加密与解密算法

C语言加密与解密算法

C语言加密与解密算法在计算机科学与信息安全领域,加密与解密算法起着至关重要的作用。

加密算法用于将原始数据转换为不可读的密文,而解密算法则用于将密文还原为可读的原始数据。

C语言是一种常用的编程语言,具备高效性和灵活性,适用于加密与解密算法的开发。

本文将介绍几种常用的C语言加密与解密算法。

一、凯撒密码算法凯撒密码算法是一种最简单的替换加密算法,通过将字母按照固定的偏移量进行替换来实现加密与解密。

以下是一个简单的C语言凯撒密码实现例子:```c#include <stdio.h>void caesarEncrypt(char* message, int key) {int i = 0;while (message[i] != '\0') {if (message[i] >= 'a' && message[i] <= 'z') {message[i] = (message[i] - 'a' + key) % 26 + 'a';} else if (message[i] >= 'A' && message[i] <= 'Z') {message[i] = (message[i] - 'A' + key) % 26 + 'A';}i++;}}void caesarDecrypt(char* message, int key) {int i = 0;while (message[i] != '\0') {if (message[i] >= 'a' && message[i] <= 'z') {message[i] = (message[i] - 'a' - key + 26) % 26 + 'a'; } else if (message[i] >= 'A' && message[i] <= 'Z') {message[i] = (message[i] - 'A' - key + 26) % 26 + 'A'; }i++;}}int main() {char message[] = "Hello, World!";int key = 3;printf("Original message: %s\n", message);caesarEncrypt(message, key);printf("Encrypted message: %s\n", message);caesarDecrypt(message, key);printf("Decrypted message: %s\n", message);return 0;}```以上程序演示了凯撒密码的加密与解密过程,通过指定偏移量实现对消息的加密与解密。

des算法的设计与实现

des算法的设计与实现

des算法的设计与实现DES(Data Encryption Standard)是一种对称加密算法,它的设计与实现涉及以下几个方面:1. 密钥生成,DES算法使用56位的密钥,通过一系列的操作生成16个子密钥,每个子密钥48位。

这些子密钥用于加密和解密过程中的轮函数。

2. 初始置换,明文经过初始置换(IP)操作,将64位明文重新排列,得到置换后的明文。

3. 轮函数,DES算法使用16轮的轮函数,每轮包括扩展置换、与子密钥的异或运算、S盒代替、P盒置换等操作。

轮函数的目的是将输入的32位数据扩展为48位,并进行一系列的混淆和置换操作。

4. S盒代替,DES算法中使用了8个不同的S盒,每个S盒输入6位,输出4位。

S盒的作用是将48位数据分成8组,每组6位,然后通过S盒进行代替操作,将6位数据转换为4位数据。

5. P盒置换,DES算法中使用了一个P盒,它对32位数据进行置换操作,重新排列数据的位置。

6. 密钥轮转,DES算法中,每轮的子密钥都是由前一轮的子密钥生成的。

轮函数中的子密钥与明文进行异或运算后,会将左右两部分数据进行交换,然后进入下一轮。

7. 逆初始置换,经过16轮的加密运算后,得到64位的密文。

最后,对密文进行逆初始置换(IP-1)操作,将64位密文重新排列,得到最终的加密结果。

DES算法的实现可以使用不同的编程语言来完成,例如C、C++、Java等。

实现时需要注意使用合适的数据结构和算法来处理数据的置换、代替和置换等操作。

同时,还需要注意保证代码的安全性和效率,避免可能存在的安全漏洞和性能问题。

总结起来,DES算法的设计与实现涉及密钥生成、初始置换、轮函数、S盒代替、P盒置换、密钥轮转和逆初始置换等方面,同时需要注意代码的安全性和效率。

des加密算法c语言源代码

des加密算法c语言源代码

#include<iostream.h>int IP[64] = {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};int IP_1[64] = {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};int E[48] = {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,1};int P[32]={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 };void Char_to_Int(unsigned char in[],int out[],int len){for(int i=0;i<len;i++)out[i]=int(in[i]);}void Int_to_Char(int in[],unsigned char out[],int len){for(int i=0;i<len;i++)out[i]=char(in[i]);}void B_to_H(int in[],unsigned char out[]){for(int i=0;i<16;i++){int temp=in[i*4]*8+in[i*4+1]*4+in[i*4+2]*2+in[i*4+3];switch(temp){case 10 :out[i]='A';break;case 11 :out[i]='B';break;case 12 :out[i]='C';break;case 13 :out[i]='D';break;case 14 :out[i]='E';break;case 15 :out[i]='F';break;default :out[i]=unsigned char(temp+48);break;}}}void H_to_B(unsigned char in[],int out[]){for(int i=0;i<16;i++)switch(in[i]){case 'A':out[i*4]=1;out[i*4+1]=0;out[i*4+2]=1;out[i*4+3]=0;break;case 'B':out[i*4]=1;out[i*4+1]=0;out[i*4+2]=1;out[i*4+3]=1;break;case 'C':out[i*4]=1;out[i*4+1]=1;out[i*4+2]=0;out[i*4+3]=0;break;case 'D':out[i*4]=1;out[i*4+1]=1;out[i*4+2]=0;out[i*4+3]=1;break;case 'E':out[i*4]=1;out[i*4+1]=1;out[i*4+2]=1;out[i*4+3]=0;break;case 'F':out[i*4]=1;out[i*4+1]=1;out[i*4+2]=1;out[i*4+3]=1;break;case '0':out[i*4]=0;out[i*4+1]=0;out[i*4+2]=0;out[i*4+3]=0;break;case '1':out[i*4]=0;out[i*4+1]=0;out[i*4+2]=0;out[i*4+3]=1;break;case '2':out[i*4]=0;out[i*4+1]=0;out[i*4+2]=1;out[i*4+3]=0;break;case '3':out[i*4]=0;out[i*4+1]=0;out[i*4+2]=1;out[i*4+3]=1;break;case '4':out[i*4]=0;out[i*4+1]=1;out[i*4+2]=0;out[i*4+3]=0;break;case '5':out[i*4]=0;out[i*4+1]=1;out[i*4+2]=0;out[i*4+3]=1;break;case '6':out[i*4]=0;out[i*4+1]=1;out[i*4+2]=1;out[i*4+3]=0;break;case '7':out[i*4]=0;out[i*4+1]=1;out[i*4+2]=1;out[i*4+3]=1;break;case '8':out[i*4]=1;out[i*4+1]=0;out[i*4+2]=0;out[i*4+3]=0;break;case '9':out[i*4]=1;out[i*4+1]=0;out[i*4+2]=0;out[i*4+3]=1;break;}}void O_to_B(int in[],int out[],int len){int i,j;for(i=0;i<len;i++)for(j=i*len+7;j>=i*len;j--){out[j]=in[i]%2; in[i]=in[i]/2;}}void B_to_O(int in[],int out[],int len){int j;for(int i=0;i<len;i++){j=8*i;out[i]=in[j]*128+in[j+1]*64+in[j+2]*32+in[j+3]*16+in[j+4]*8+in[j+5]*4+in[j+6]*2+in[j+7]*1;}}void Convert(int in[],int out[],int table[],int len){for(int i=0;i<len;i++)out[i]=in[table[i]-1];}void Divide(int in[],int out1[],int out2[],int len){for(int i=0;i<len;i++)if(i<len/2)out1[i]=in[i];elseout2[i-len/2]=in[i];}//正确void Combine(int in1[],int in2[],int out[],int len){for(int i=0;i<len;i++)if(i<len/2)out[i]=in1[i];elseout[i]=in2[i-len/2];}//正确void RLC1(int in[],int out[],int len){int temp=in[0];for(int i=0;i<len-1;i++)out[i]=in[i+1];out[len-1]=temp;}//正确void RLC2(int in[],int out[],int len){int temp1=in[0],temp2=in[1];for(int i=0;i<len-2;i++)out[i]=in[i+2];out[len-2]=temp1;out[len-1]=temp2;}//正确void COPY(int in[],int out[],int len){for(int i=0;i<len;i++)out[i]=in[i];}//ZHENGQUEvoid XOR(int in1[],int in2[],int out[],int len){for(int i=0;i<len;i++)out[i]=(in1[i]+in2[i])%2;}void GetKey(unsigned char in[],int out[16][48]){int i;int Msg_Int[8],Msg_Bin[64],Msg_Bin_PC1[56],Key_Bin[56],C[17][28],D[17][28];char Msg_H[16];int PC1[56]={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},PC2[48]={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};Char_to_Int(in,Msg_Int,8);//正确O_to_B(Msg_Int,Msg_Bin,8);//正确cout<<endl;Convert(Msg_Bin,Msg_Bin_PC1,PC1,56); Divide(Msg_Bin_PC1,C[0],D[0],56);for(i=0;i<16;i++){if(i==0){RLC1(C[i],C[i+1],28);RLC1(D[i],D[i+1],28);}else if(i==1){RLC1(C[i],C[i+1],28);RLC1(D[i],D[i+1],28);}else if(i==8){RLC1(C[i],C[i+1],28);RLC1(D[i],D[i+1],28);}else if(i==15){RLC1(C[i],C[i+1],28);RLC1(D[i],D[i+1],28);}else{RLC2(C[i],C[i+1],28);RLC2(D[i],D[i+1],28);}Combine(C[i+1],D[i+1],Key_Bin,56);Convert(Key_Bin,out[i],PC2,48);}} //生成子密钥正确void S_box(int in[],int out[]){int i;int SBox[8][64] ={{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 s1,s3,s2[8];for(i=0;i<8;i++){s1=in[i*6]*2+in[i*6+5]*1;s3=in[i*6+1]*8+in[i*6+2]*4+in[i*6+3]*2+in[i*6+4]*1;s2[i]=SBox[i][s1*16+s3];}int j;for(i=0;i<8;i++)for(j=i*4+3;j>=i*4;j--){out[j]=s2[i]%2; s2[i]=s2[i]/2;}}void Encode(unsigned char in[],unsigned char Final_H[],int K[16][48]){int i;intORINT[8],ORBYTE[64],FinalBYTE[64],LR[64],R48[48],S_in[48],S_out[32],F_RL[32],FinalINT[8],L[17] [32],R[17][32];char ORH[16];Char_to_Int(in,ORINT,8);cout<<""<<endl;O_to_B(ORINT,ORBYTE,8);Convert(ORBYTE,LR,IP,64);Divide(LR,L[0],R[0],64);for(i=1;i<17;i++){Convert(R[i-1],R48,E,48);XOR(R48,K[i-1],S_in,48);S_box(S_in,S_out);Convert(S_out,F_RL,P,32);XOR(F_RL,L[i-1],R[i],32);COPY(R[i-1],L[i],32);}Combine(R[16],L[16],LR,64);Convert(LR,FinalBYTE,IP_1,64);cout<<"二进制的密文:"<<endl;for(i=0;i<64;i++){cout<<FinalBYTE[i];}cout<<endl<<endl;B_to_H(FinalBYTE,Final_H);}void DeCode(unsigned char in[],unsigned char Final_H[],int K[16][48]){int i;intORINT[8],ORBYTE[64],LR[64],R48[48],S_in[48],S_out[32],F_RL[32],FinalBYTE[64],FinalINT[8],L[17] [32],R[17][32];char ORH[16];Char_to_Int(in,ORINT,8);cout<<""<<endl;O_to_B(ORINT,ORBYTE,8);Convert(ORBYTE,LR,IP,64);Divide(LR,L[0],R[0],64);for(i=1;i<17;i++){COPY(R[i-1],L[i],32);Convert(R[i-1],R48,E,48);XOR(R48,K[16-i],S_in,48);S_box(S_in,S_out);Convert(S_out,F_RL,P,32);XOR(L[i-1],F_RL,R[i],32);}Combine(R[16],L[16],LR,64);Convert(LR,FinalBYTE,IP_1,64);B_to_H(FinalBYTE,Final_H);}void main(){int i;unsigned char Msg[8],UnCodeMsg[16],CodeMsg[16],Key[8],Msg_H[16],CodeChar[8];int SKey[16][48];int OrByte[64],OrInt[8],FinalByte[64],FinalInt[8];cout<<"请输入明文:"<<endl;for(i=0;i<8;i++)cin>>Msg[i];cout<<"请输入初始密钥:"<<endl;for(i=0;i<8;i++)cin>>Key[i];GetKey(Key,SKey);Encode(Msg,CodeMsg,SKey);cout<<"十六进制的密文:"<<endl;for(i=0;i<16;i++)cout<<CodeMsg[i];cout<<endl;cout<<"字符型密文:"<<endl;H_to_B(CodeMsg,FinalByte);B_to_O(FinalByte,FinalInt,8);Int_to_Char(FinalInt,CodeChar,8);for(i=0;i<8;i++)cout<<CodeChar[i];cout<<endl;cout<<"请输入十六进制的密文:"<<endl;for(i=0;i<16;i++)cin>>CodeMsg[i];B_to_O(FinalByte,FinalInt,8);Int_to_Char(FinalInt,CodeChar,8);cout<<"请输入解密密钥:"<<endl;for(i=0;i<8;i++)cin>>Key[i];GetKey(Key,SKey);DeCode(CodeChar,Msg_H,SKey);//for(i=0;i<16;i++)// cout<<Msg_H[i];cout<<endl;H_to_B(Msg_H,OrByte);B_to_O(OrByte,OrInt,8);Int_to_Char(OrInt,Msg,8);cout<<"明文是:"<<endl;for(i=0;i<8;i++)cout<<Msg[i];cout<<endl;}。

DES加密的算法

DES加密的算法

信息安全概论·课程设计DES加密的C语言实现目录摘要....................................................... 错误!未定义书签。

Abstract ................................................... 错误!未定义书签。

关键词..................................................... 错误!未定义书签。

1.算法描述................................................ 错误!未定义书签。

1.1加/解密算法的一般原理............................... 错误!未定义书签。

1.2加/解密机制的应用................................... 错误!未定义书签。

2.S盒设计................................................ 错误!未定义书签。

3.DES程序实例与分析...................................... 错误!未定义书签。

4.DES实例运行结果........................................ 错误!未定义书签。

5.结语.................................................... 错误!未定义书签。

6.参考文献................................................. 错误!未定义书签。

信息安全概论·课程设计DES加密的C语言实现C language achieve DES algorithm摘要DES算法是一种数据加密算法,自从1977年公布以来,一直是国际上的商用保密通信和计算机通信的最常用的加密标准。

DES算法的C语言实现

DES算法的C语言实现

DES算法的程序实现说明:在VC++6.0中新建基于控制台的Win32应用程序,程序清单如下:#iinclude “memory.h”#include “stdio.h”Enum {ENCRYPT,DECRYPT}Void Des_Run(char Out[8],char In[8],bool Type=ENCRYPT); //设置密钥Void Des_SetKey(const char Key[8]);Static void F_func(bool In[32],const bool Ki[48]); //f函数Static void s_func(bool Out[32],const bool In[48]); //S盒代替Static void Transform(bool *out,bool *In,const char *Table,int len); //变换Static void Xor(bool *InA,const bool *InB,int len); //异或Static void RotateL(bool *In,int len,int loop);//循环左移//字节组转换成位组Static void ByteToBit(bool *out,const char *In,int bits);//位组转换成字节组Static void BitToByte(char *Out,const bool *In,int bits);//置换IP表Const static char IP_Table[64]={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};//逆置换IP-1表Const static char IPR_Table[64]={40,8,48,16,56,24,64,32,39,7,47,15,55,3138,6,46,14,54,22,62,30,37,5,45,13,53,21,61,2936,4,44,12,52,20,60,28,35,3,43,11,51,19,59,2734,2,42,10,50,18,58,26,23,1,41,9,49,17,57,25};//逆置换IP-1表Const static char IPR_Table[64]={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};//E位选择表Static const char E_Table[48]={32,1,2,3,4,5,6,7,8,9,8,9,10,11,12,13,14,15,16,17,16,17,18,19,20,21,22,23,24,25,24,25,26,27,28,29,30,31,32,1};//P换位表Const static char P_Table[32]={Const static char P_Table[32]={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 };//PC1选位表Const static char PC1_Table[56]={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};//PC2选位表Const static char PC2_Table[48]={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,34,33,48,44,49,39,56,34,53,46,42,50,36,29,32};//左移位数表Const static char LOOP_Table[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};//S盒Const static char S_Box[8][4][16]={//S114,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,//S215,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,//S310,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,//S47,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,//S52,12,4,1,7,10,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,//S612,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,10,15,4,2,7,12,0,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,//S74,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,13,0,11,7,4,0,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,26,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12,//S813,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};Static bool SubKey[16][48]; //16圈子密钥Void Des_Run(char Out[8],char In[8],bool Type){Static bool M[64],Tmp[32],*Li=&M[0],*Ri=&M[32]; ByteToBit(M,In,64);Transform (M,M,IP_Table,64);If (Type==ENCRYPT){For (int i=0;i<16;i++){memcpy(Tmp,ri,32);F_func(Ri,SubKey[i]);Xor(Ri,Li,32);Memcpy(Li,Tmp,32);}}else{For (int i=15;i>=0;i--) {Memcpy(Tmp,Li,32);F_func(Li,SubKey[i]);Xor(Li,Ri,32);Memcpy(Ri,Tmp,32);}}Transform(M,M,IPR_Table,64);BitToByte(Out,M,64);}Void Des_SetKey(const char Key[8]){Static bool K[64],*KL=&K[0],*KR=&K[28];ByteToBit(K,Key,64);Transform(K,K,PC1_Table,56);For (int i=0;i<16;i++){RotateL(KL,28,LOOP_Table[i]);RotateL(KR,28,LOOP_Table[i]);Transform(SubKey[i],K,PC2_Table,48);}}Void F_func(bool In[32],const bool Ki[48]){static bool MR[48];Transform(MR,In,E_Table,48);Xor(MR,Ki,48);S_func(In,MR);Transform(In,In,P_Table,32);}Void S_func(bool Out[32],const bool In[48]){For (char i=0,j,k;i<8;i++;In+=6,Out+=4){J=(In[0]<<1)+In[5];K=(In[1]<<3)+(In[2]<<2)+(In[3]<<1)+In[4];ByteToBit(Out,&S_Box[i][j][k],4);}}Void Transform(bool *Out,bool *In,const char *Table,int len) {Static bool Tmp[256];For (int i=0;i<len;i++)Tmp[i]=In[Table[i]-1];Memcpy(Out,Tmp,len);}Void Xor(bool *InA,const bool *InB,int len){For (int i=0;i<len;i++)InA[i]^=InB[i];}Void RotateL(bool *In,int len,int loop){Static bool Tmp[256];Memcpy(Tmp,In,loop);Memcpy(In,In+loop,len-loop);Memcpy(In+len-loop,Tmp,loop);}}Void ByteToBit(bool *Out,const char *In,int bits){For (int i=0;i<bits;i++)Out[i]=(In[i/8]>>(i%8)) &1;}Void BitToByte(char *Out,const bool *In,int bits){Memset (Out,0,(bits+7)/8);For (int i=0;i<bits;i++)Out[i/8]!=In[i]<<(i%8);}Void main(){char key[8]={1,9,8,0,9,1,7,2},str[]=”Hello”;Puts(“Before encrypting”);Puts(str);Des_SetKey(key);Des_Run(str,str,ENCRYPT); //调用Des_Run函数对输入的明文进行加密//其中第1个参数str是输出的密文,第2个参数str是输入的明文Puts(“After encrypting”);Puts(str);Puts(“After decrypting”);Des_Run(str,str,DECRYPT);Puts(str);}。

des密码算法程序c语言

des密码算法程序c语言

des密码算法程序c语言一、概述DES(数据加密标准)是一种常用的对称加密算法,它采用64位的密钥,对数据进行加密和解密。

本程序使用C语言实现DES算法,包括密钥生成、数据加密和解密等操作。

二、算法实现1.密钥生成:使用初始置换算法IP(56位)将明文转化为56位的分组,再将该分组经过一系列的逻辑函数F进行6轮处理,最终生成一个56位的密文。

其中密钥包括56位数据位和8位奇偶校验位。

2.数据加密:将需要加密的数据转化为56位的分组,再经过DES 算法处理,得到密文。

3.数据解密:将密文经过DES算法处理,还原成原始明文。

三、程序代码```c#include<stdio.h>#include<string.h>#include<stdlib.h>#include<time.h>//DES算法参数定义#defineITERATIONS6//加密轮数#defineKEY_LENGTH8//密钥长度,单位为字节#defineBLOCK_SIZE8//数据分组长度,单位为字节#definePADDINGPKCS7Padding//填充方式#defineMAX_INPUT_LENGTH(BLOCK_SIZE*2)//数据输入的最大长度//初始置换函数voidinit_permutation(unsignedcharinput[BLOCK_SIZE]){inti;for(i=0;i<BLOCK_SIZE;i++){input[i]=i;}}//逻辑函数F的定义voidlogic_function(unsignedcharinput[BLOCK_SIZE],unsigned charoutput[BLOCK_SIZE]){inti;for(i=0;i<BLOCK_SIZE;i++){output[i]=input[(i+1)%BLOCK_SIZE]^input[i]^(i+1)/BLOCK_SI ZE;}}//DES算法主函数voiddes_encrypt(unsignedchar*input,unsignedchar*output){ unsignedcharkey[KEY_LENGTH];//密钥数组unsignedchariv[BLOCK_SIZE];//初始置换的输入数组unsignedcharciphertext[MAX_INPUT_LENGTH];//密文数组unsignedcharpadding[BLOCK_SIZE];//填充数组unsignedintlength=strlen((char*)input);//数据长度(以字节为单位)unsignedintpadding_length=(length+BLOCK_SIZE-1)%BLOCK_SIZE;//需要填充的字节数unsignedintround=0;//加密轮数计数器unsignedintj=0;//数据指针,用于循环读取数据和填充数据intkey_offset=((1<<(32-KEY_LENGTH))-1)<<(32-(ITERATIONS*BLOCK_SIZE));//密钥索引值,用于生成密钥数组和填充数组的初始值unsignedintk=0;//DES算法中每个轮次的密钥索引值,用于生成每个轮次的密钥数组和填充数组的值unsignedintkplus1=(k+1)%((1<<(32-BLOCK_SIZE))-1);//DES算法中每个轮次的密钥索引值加一后的值,用于下一个轮次的密钥生成charseed[32];//使用MD5作为初始种子值生成随机数序列chartmp[MAX_INPUT_LENGTH];//临时变量数组,用于数据交换和中间计算结果存储等操作time_tt;//时间戳变量,用于生成随机数序列的种子值srand((unsignedint)time(&t));//设置随机数种子值,确保每次运行生成的随机数序列不同init_permutation(iv);//初始置换操作,将输入数据转化为56位分组(需要重复填充时)或一个随机的分组(不需要重复填充时)memcpy(key,key_offset,sizeof(key));//将初始化的密钥数组复制到相应的位置上,以便于接下来的轮次生成不同的密钥值memcpy(padding,seed,sizeof(seed));//将种子值复制到填充数组中,以便于接下来的轮次生成不同的随机数序列值for(round=0;round<ITERATIONS;round++){//进行加密轮次操作,每轮包括。

DES算法C实现

DES算法C实现

数据加密标准算法DES摘要:DES算法全称为Data Encryption Standard,即数据加密算法,它是IBM 公司于1975年研究成功并公开发表的。

DES算法的入口参数有三个:Key、Data、Mode。

其中Key为8个字节共64位,是DES算法的工作密钥; Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。

关键字:密码生命周期DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位。

DES算法是一种标准的对称加密算法,其精华就是把明文经过一系列的复杂变化后搞的面目全非,一般在不知密码的情况下要把它的恢复很难。

算法可以由四个部分描述:1.获取16个子密钥 2.初始置换置换函数ip 3.加密函数f 4.末置换函数以下是分解动作:1.获取16个子密钥:密码是64位的布尔值,经过以下步骤得到16个48位的字密钥:(1)去掉每个第八位,然后通过置换表,得到56位的子密钥(2) 分成前后28位(3)根据表对前后28为进行1~16轮的1或2位的循环(4)移位后,再将两部分合并成56位,然后通过压缩置换得到48位子密钥2.初始置换函数:就是把64位的明文根据置换表置换成56位的明文,然后分成左右两部分3.密码函数f密码函数F的输入为32位的数据和48位的子密E是扩展置换,把32位部分明文扩展成48位再与48的子密钥抑或,再经过s盒转化,成32位输出,最后再经过一个置换(p盒)就得到了密码函数的输出了。

然后把密码函数的输出跟初始置换后的左边32位抑或,结果作为新明文的后边,原右边作为新左边。

然后用16个子密钥重复上面的行为。

s盒的过程:把48位分成8个6位,取6位的第一位和最后一位,这两位组成的数作为s盒的行,其他三位作为列,知道行列后就在s盒表中查到对应的的数,这个数是4位的,就用这个4位的数代替该6位的数。

所以最后出来的是32位了。

DES_加密解密算法的C++实现

DES_加密解密算法的C++实现
private: string plaintextFilePath_;/*明文文件路径*/ string ciphertextFilePath_;/*密文文件路径*/ string keyFilename_;/*密钥文件路径*/
string plaintext_;/*明文存储*/ string ciphertext_;/*密文存储*/ string key_;/*密钥存储*/
const unsigned int DES::IPR_[64] = { 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 };
算法的整体结构:有 16 个相同的处理过程,称为“回次”,并在首位各 有一次置换。在主处理回次前,数据块被分成两个 32 位的半块,并被分别 处理。图中的⊕符号代表异或操作。“F 函数”将数据半块与某个子密钥进行 处理。然后,一个 F 函数的输出与另一个半块异或之后,再与原本的半块 组合并交换顺序,进入下一个回次的处理。在最后一个回次完成时,两个 半块不必交换顺序 。
const unsigned int DES::PC_1_[56] = { /*注释的部分是对应 64 位带奇偶校验的*/ /*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*/ 50, 43, 36, 29, 22, 15, 8, 1, 51, 44, 37, 30, 23, 16, 9, 2, 52, 45, 38, 31, 24, 17, 10, 3, 53, 46, 39, 32, 56, 49, 42, 35, 28, 21, 14, 7, 55, 48, 41, 34, 27, 20, 13, 6, 54, 47, 40, 33, 26, 19, 12, 5, 25, 18, 11, 4 };

基于C语言的网络通信DES加密算法分析

基于C语言的网络通信DES加密算法分析

2021.51数据加密理论基础通常情况下,被加密的数据被称为“密文”,将密文转化为明文的这一操作被称为“解密”[1]。

数据加密解密过程如图1所示。

数据加密算法主要包含以下3种类型:(1)DES 加密算法。

该算法又被称为“数据加密标准”,被视为一种常用的数据加密算法,该算法在具体的运用中,所使用的加密密钥和解密密钥是相同的,因此,DES 加密算法具有加密速率高、安全可靠等特征。

(2)RSA 数据加密算法。

该算法作为一种公开密钥算法,主要用于对数据的加密和签名处理[2]。

(3)DSA 数据签名算法。

2DES 加密算法原理与实现2.1DES 加密算法原理DES 加密算法主要是在Lucifer 算法中演变而来的,该算法属于一种分组加密算法,以64位为数据分组单位,对分组后的数据进行加密保护处理,然后,将64位一组的数据以明文的形式输入到系统内,系统利用DES 加密算法,将明文转化为密文,并从另一端输出密文。

DES 加密算法属于一种对称算法,而数据加密处理和数据解密处理均用到了同一种算法。

密钥的长度通常为56位,56位数据可以任意选取的,因此,有少量的数据被称为“弱密钥”,所以,为了提高数据的保密性,技术人员要重视对密钥的应用。

另外,DES 加密算法在对64位明文进行分组加密处理时,需要采用数据置换的方式,将明文划分为以下两种类型,一种是左半部分数据,另一种是右半部分数据。

这两种类型的数据长度均为32位,然后,利用密钥,对将左半部分数据和右半部分数据进行有效结合,并采用逆置换的方式,实现对数据的加密保护,为进一步提高数据传输的稳定性、可靠性和安全性打下坚实的基础。

由此可见,DES 加密流程主要涉及到以下几点:(1)采用重新排序的方式,将明文以64位为一组进行分组,然后,对其进行初始化置换处理,从而得到长度均32为的左半部分数据和右半部分数据。

(2)对两半部分的数据进行迭代处理,从而获得16次变换处理。

(3)采用逆置换的方式,将两半部分数据对调,从而生成相应的密文。

C语言实现DES加密解密算法

C语言实现DES加密解密算法

C语言实现DES加密解密算法
最近几十年里,DES(Data Encryption Standard)算法的发展起到
了极其重要的作用。

Des算法是一种基于分组密码的算法。

算法将64位
的明文数据块按位分组成8个字节,每一组以8位为单位转换成一个64
位的密文数据块,采用16轮的分组加密,每次密码变化,保证加密强度。

本文详细介绍了DES算法的C语言实现,并分别介绍了加解密算法的实现
步骤以及DES加解密测试过程。

一、DES算法C语言实现
1.函数原型
DES算法的实现包括加密和解密函数,函数原型如下:
unsigned char* DesEncrypt(unsigned char *src, unsigned char
*key); // DES加密函数
unsigned char* DesDecrypt(unsigned char *src, unsigned char
*key); // DES解密函数
输入参数src是指明文源数据,key是加解密密钥,输出参数为一个
指向加解密结果的字符串指针。

2.加解密算法
(1)DES加密算法
DES加密算法步骤如下:
(i)初始置换:将64位明文块做一次IP置换得到L0R0。

(ii)迭代轮换:对L0R0经过16次迭代轮换后,最终结果为
L16R16
(iii)逆置换:L16R16进行逆置换得到64位密文。

(2)DES解密算法
DES解密算法步骤和DES加密算法步骤是一样的,只是将置换步骤改为逆置换,将轮换步骤改为逆轮换即可。

三、DES加解密测试
1.程序测试
在C语言编写完DES加解密算法之后。

C语言实现数据加密算法

C语言实现数据加密算法

C语言实现数据加密算法数据加密是对敏感信息进行转换的过程,以保护数据的机密性和完整性。

C语言提供了强大的工具和库来实现各种加密算法,包括对称加密和非对称加密等。

对称加密算法是一种使用相同密钥加密和解密数据的方法。

其中最常见的算法是DES(Data Encryption Standard)和AES(Advanced Encryption Standard)。

下面是一个实现AES算法的示例代码:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <openssl/aes.h>void encrypt_data(const unsigned char *data, size_t len, const unsigned char *key, unsigned char *encrypted_data) AES_KEY aes_key;AES_set_encrypt_key(key, 128, &aes_key);AES_encrypt(data, encrypted_data, &aes_key);void decrypt_data(const unsigned char *encrypted_data,size_t len, const unsigned char *key, unsigned char *data) AES_KEY aes_key;AES_set_decrypt_key(key, 128, &aes_key);AES_decrypt(encrypted_data, data, &aes_key);int maiunsigned char data[AES_BLOCK_SIZE] = "hello world!";size_t len = sizeof(data);unsigned char encrypted_data[AES_BLOCK_SIZE];encrypt_data(data, len, key, encrypted_data);unsigned char decrypted_data[AES_BLOCK_SIZE];decrypt_data(encrypted_data, len, key, decrypted_data);printf("Original Data: %s\n", data);printf("Encrypted Data: ");for (int i = 0; i < len; i++)printf("%02x ", encrypted_data[i]);}printf("\nDecrypted Data: %s\n", decrypted_data);return 0;```以上代码使用了OpenSSL库中的AES加密算法。

DES加密算法的C语言实现

DES加密算法的C语言实现

DES加密算法的C语言实现DES(Data Encryption Standard)是一种对称密钥加密算法,它的核心思想是将明文分成64位的数据块,并通过一系列的轮次操作对数据块进行加密,最终得到密文。

下面是一种用C语言实现DES加密算法的示例代码:```c#include <stdio.h>unsigned char initial_permutation(unsigned char block)unsigned char result = 0;result ,= (block & 0x80) >> 7;result ,= (block & 0x40) >> 5;result ,= (block & 0x20) >> 3;result ,= (block & 0x10) >> 1;result ,= (block & 0x08) << 1;result ,= (block & 0x04) << 3;result ,= (block & 0x02) << 5;result ,= (block & 0x01) << 7;return result;unsigned char final_permutation(unsigned char block)unsigned char result = 0;result ,= (block & 0x80) >> 7;result ,= (block & 0x40) >> 5;result ,= (block & 0x20) >> 3;result ,= (block & 0x10) >> 1;result ,= (block & 0x08) << 1;result ,= (block & 0x04) << 3;result ,= (block & 0x02) << 5;result ,= (block & 0x01) << 7;return result;void des_encrypt(unsigned char* plaintext, unsigned char* key, unsigned char* ciphertext)unsigned char block;unsigned char round_key;unsigned char i;// Initial Permutationblock = initial_permutation(*plaintext);// Round Permutationfor (i = 0; i < 16; i++)round_key = key[i];block ^= round_key;block = substitution(block);block = permutation(block);}// Final Permutation*ciphertext = final_permutation(block);int maiunsigned char plaintext = 0x55; // 明文unsigned char key[16] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}; // 密钥unsigned char ciphertext;des_encrypt(&plaintext, key, &ciphertext);printf("明文: 0x%02X\n", plaintext);printf("密钥: ");for (unsigned char i = 0; i < 16; i++)printf("%02X ", key[i]);}printf("\n");printf("密文: 0x%02X\n", ciphertext);return 0;```上述代码实现了DES算法的加密功能。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

DES加密算法C实现网上流传着众多DES加密算法的不同版本,原理相同,代码亦大同小异,而大多却是出自同源,在这呢,我也公布一种我自己的写法,也不一定好,但求容易看懂。

步骤详解:1.密钥处理:得到16轮操作,每轮所需要用到的密钥;为什么这样做呢?因为大家知道:加密解密用的16个密钥是相同的,只是顺序不同,如果先将要用到的16轮密钥都求出呢,以后不论加密还是解密便可直接调用,不用再想它了。

2.明文处理:即初始置换啊,16轮迭代啊神马的这一步呢,就把所有需要做的操作做完了。

也就是说呢,第2步处理之后,便可以输出密文了。

综上可以看出,DES加/解密,其实就两步操作,一呢,得到密钥,二,就是对明/密文进得处理。

好了,下面我们仔细看看以上两步的详细操作流程:首先,是得到16轮密钥这一步,我们知道:其中第8、16、24、32、40、48、56、64位是没有用到的,也就是有些地方说的奇偶校验位,说白了,反正都没用到,你还管他奇偶校验去死啊(其实这样说有问题,因为奇偶校验位可以验证密码,但在一般实现中这个作用都没有体现出来,所以,在这,你大可以大胆放心滴让它去死~)。

那,说到这呢,我就想曝光一个事实:网上众多的DES实现代码中,有相当多的一部分在这一步上都有问题,不信的话你可以去试验一下,包括“在线DES加密解密”中,你可以对明文用诸如“12345678”进行加密,然后用“03254769”进行解密,你会发现,解密出来,仍然是原来的明文,可是密钥明明就不是原来的密钥嘛为什么会这样呢,留给亲爱的读者你去想喽。

呃,跑题了,书接前文:话说这8位没用的话,那我们就应该跳过这8位,所以在对密钥进行处理时呢,我们可以对密钥的字符直接左移1位(这样做的后果就是舍去高位,但只要设置成不能用中文密钥进行加/解密就不会有问题了)以跳过8的倍数位,然后再进行初始置换,左移,压缩置换。

在这里插一句哈,我们直接用位操作来实现的话呢,不是不可以,只是操作比较烦,也容易出错,所以我们可以选择将字符转换成对应的二进制来操作,即以8位(1字符)来代表原来字符中的一位,等操作完成后再转换回来。

那我们就会用到两个函数:1.void ChToBit(char* dest, char* src, int length); // 字符转二进制2.inline void BitToCh(char* dest, char* src, int length); // 二进制转字符那现在问题就是如何进行置换?我们应该知道,在这之后对明文的处理过程中也会有很多置换处理,我们会发现一个特点,那就是:过程都一样,只是用到的置换数组不一样,那么我们就完全可以将它们统统用一个函数来实现:1.void BatchSet(char* dest, char* src, char* offset, int count);它的作用就是将src[]中的字符按照offset[]置换到dest[]中,count要置换的字符个数。

它的实现很简单,就是单纯地将src[]中的字符以offset[]为下标一个个地写到dest[]中。

(具体见代码实现)好了,置换已经被我们干掉了,下一关就是左移了。

在这呢,很多人想到的方法是用memcpy()进行位移,但是我们的C提供了指针啊,设:指针指向字符串的开始,然后我们完全可以这么想:字符左移,就相当于指针右移。

即算法要求左移多少位,指针就右移多少位。

这样做方便省事,只是要多花一点空间,反正那么多盒的空间都用了,这20来个字符的空间还舍不行呀。

那么,现在,左移也被我们愉快地解决啦。

(具体见代码实现)OK, OK. 前面我们已经得到了16轮要用到的密钥,下面我们就可以进入DES加密解密的主要过程了。

将明文转为对应的二进制后,首先呢,是对明文进行初始置换,置换怎么做?Alright, BatchSet()一步搞定!然后进入16轮的迭代过程:一,扩展置换,反正是置换就BatchSet()了,过;二,与得到的密钥进行异或操作,额,这就不说了吧;三,S_BOX 代替,这个就是考位操作了,一般没问题吧,将得到的S_BOX中的值拼装后进行个转换二进制就行了;四,P_BOX置换,还是BatchSet();五,与左半部分进行异或,不说了,过;六,将原右半部分写到左半部分。

16轮迭代完成后将左右部分交换一下,再来个末置换,就算是加密完成了。

最后,再将密文可读就行了。

密文可读,什么意思?你想呀,我们用的是C嘛,C中字符串是以0为结束符的,假设,在密文的中间部分出现了0怎么办?输出都是问题呀。

再假设,如果密文的字符二进制是以1为开始的怎么办?让它出现中文乱码?显然这样做不太美观,所以我们可以想个办法让它可读,这里我用输出它对应十六进制的方法,当然也可以用其它任何适当方法。

下面就用一些更直接的表现一下具体过程吧:一,得到密钥部分1.key[0..7] <<= 1; // 跳过每个字符的第8位2.bk[1..64] <-- key // 转为二进制3.初始转换得到tk <-- bk,同时使指针ptk = tk // BatchSet初始置换4.左移相应的位数,但只是ptk += 位移数5.压缩置换得到keyb[i] // keyb[0..15][1..48]即为每轮要用到的密钥6.重复4,5共16次二,得到密文部分1.msgbt <-- msg 得到二进制2.msgb <-- msgbt 初始置换3.rt <-- msgb+33 将右半部分先保存起来4.r <-- msgb+32 扩展置换到r[]中5.r ^= keyb ; r与每轮密钥keyb进行异或6.r = S盒代替(r); 进行S盒代替7.msgb+32 <-- r; P盒置换8.(msgb+32)[1..32] ^ msgb[1..32] 右半部分与左半部分进行异或9.msgb+1 <-- rt 将原来的右半部分写到左半部分10.重复3~9共16次11.交换msgb左右两部分12.msgb末置换14.使密文可读其实16轮具体过程呢,就是如下咯:设L0为明文左半部分,R0为明文右半部分,i表示第i轮,ER表示扩展置换(TR = Ri) --> (扩展置换Ri得到ER) --> (ER^=key[i]) --> (S盒代替得到ER) --> (P盒置换ER得到Ri) --> (Ri^=Li) --> (Li=TR)代码实现:// 理论支持明文长度// 加密用的宏// 解密用的宏// 明文初始置换msg_ch[64] = {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 };// 密钥初始置换key_ch[56] = {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};// 扩展置换msg_ex[48] = {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, 1};// 每轮密钥的位移key_mov[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};// 压缩置换key_cmprs[48] = {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};// S 盒置换s_box[8][4][16] = {// S114, 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, // S215, 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, // S310, 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, // S47, 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, // S52, 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, // S612, 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, // S74, 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, // S813, 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};// P 盒置换p_box[32] = {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};// 末置换last_ch[64] = {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};// hash 置换,将加密后的密文置换为可读明文hs_ch[20] = "0123456789abcdef";sh_ch[128];msg[maxn], key[16], res[32];msgb[72], msgbt[72], keyb[18][72];// 字符转成二进制inline ChToBit(* dest, * src, length) { for ( i = 0; i < length; i++)for ( j = 8, t = src[i]; j > 0; j--) {dest[(i << 3) + j] = t & 1; // 取字符末位t >>= 1;}}// 二进制转成字符inline BitToCh(* dest, * src, length) { for ( i = 0; i < length << 3; i++) {dest[i >> 3] <<= 1;dest[i >> 3] |= src[i + 1]; // 添加到末位}dest[length] = 0;}// 批置换,以offset为偏移,以count为长度inline BatchSet(* dest, * src, * offset, count) {for ( i = 0; i < count; i++)dest[i + 1] = src[offset[i]];}// 得到16轮所需的密钥inline getKeys() {tk[128], bk[72];* ptk = tk;for ( i = 0; i < 8; i++)key[i] <<= 1; // 跳过奇偶校验位ChToBit(bk, key, 8);BatchSet(tk, bk, key_ch, 56);for ( i = 0; i < 16; i++) {for ( j = 0; j < key_mov[i]; j++, ptk++) {ptk[57] = ptk[28];ptk[28] = ptk[1];// ptk++ 为亮点所在,实质上每一位都没有左移,只是指针右移了 }BatchSet(keyb[i], ptk, key_cmprs, 48);}}// 将加密后的密文转换为可读的明文msgPro(* dest, * src) {i, j;for (i = 0; i < 16; i++) {dest[i] = 0;for (j = 1; j <= 4; j++) // 取4位按hash构造一个字符dest[i] = (dest[i] << 1) | src[i * 4 + j];dest[i] = hs_ch[dest[i]];}dest[i] = 0;}// 将密文转换为真正的密文dropMsg(* dest, * src) {for ( i = 0; i < 16; i++) // 为hash的逆运算过程dest[i >> 1] = (dest[i >> 1] << 4) | sh_ch[src[i]];}// 通用加/解密函数,后面三个参数由宏ENCODE和DECODE提供DES(* pmsg, st, cl, step) {i, row, col;r[64], rt[48], s[8];ChToBit(msgbt, pmsg, 8);BatchSet(msgb, msgbt, msg_ch, 64); // 初始置换for (; st != cl; st += step) {memcpy(rt, msgb + 33, 32);BatchSet(r, msgb + 32, msg_ex, 48); // 扩展置换for (i = 1; i <= 48; i++)r[i] ^= keyb[st][i]; // 异或操作// s_box 代替for (i = 0; i < 48; i += 6) {row = col = 0;row = r[i + 1] << 1 | r[i + 6];col = (r[i + 2] << 3) | (r[i + 3] << 2) | (r[i + 4] << 1) | r[i + 5];s[i / 12] = (s[i / 12] <<= 4) | s_box[i / 6][row][col]; }ChToBit(r, s, 4);BatchSet(msgb + 32, r, p_box, 32); // p_box 置换for (i = 1; i <= 32; i++)msgb[i + 32] ^= msgb[i]; // 异或memcpy(msgb + 1, rt, 32);}memcpy(msgbt + 33, msgb + 1, 32);memcpy(msgbt + 1, msgb + 33, 32);BatchSet(msgb, msgbt, last_ch, 64); // 末置换if (step == 1)msgPro(res, msgb); // 使密文可读elseBitToCh(res, msgb, 8); // 转为原明文}/* 本程序为其他程序调用,所有参数自己定义* 详细参数:* des d/e key msg* d——解密 e——加密* key——密钥* msg——要加/解密的明/密文*/main( arg, * arv[]) {if (arg < 3) {printf("Input Error");return 0;}for ( i = 0; i < 16; i++)sh_ch[hs_ch[i]] = i; // 完成hash转换的对应// 读取参数过程char mode = arv[1][0];strcpy(key, arv[2]);strcpy(msg, arv[3]);getKeys(); // 得到16轮要用到的密钥if (mode == 'e') {for (int i = 0; msg[i]; i += 8) {DES(msg + i, ENCODE); // 加密printf(res);}} else if (mode == 'd') {for (int i = 0; msg[i]; i += 16) {dropMsg(res, msg + i); // 将密文转换为真正的密文 DES(res, DECODE); // 解密printf(res);}} else {printf("Input Error");}return 0;}测试:。

相关文档
最新文档