/*
*This program is about the DES algorithm.
*Author : Ting
*E-mail:kilvdn@yahoo.com.cn
*Addr: China University of Geosciences ( WuHan )
*/
#include <stdio.h>
#include <string.h>
int key[64] , tempkey[56] , subkey[16][48] ;
int choose ;
//置换选择1的矩阵
int zhxz1[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
};
//置换选择2的矩阵
int zhxz2[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 shiftleft[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
//置换选择1
void ChooseI(){
for (int i=0; i<56; i++)
tempkey[i] = key[zhxz1[i]-1];
}
//置换选择2,找出一个48位的子密钥
void ChooseSubKey( int n ){
for (int i=0; i<48; i++)
subkey[n][i]=tempkey[zhxz2[i]-1];
}
//循环左移n位
void ShiftL( int n ){
int temp ;
temp = tempkey[0];
for ( int i=0; i<27; i++ )
tempkey[i]=tempkey[i+1];
tempkey[27]=temp;
temp = tempkey[28] ;
for ( int i=28; i<55; i++ )
tempkey[i]=tempkey[i+1];
tempkey[55]=temp;
if (shiftleft[n]==2){
temp = tempkey[0];
for ( int i=0; i<27; i++ )
tempkey[i]=tempkey[i+1];
tempkey[27]=temp;
temp = tempkey[28] ;
for ( int i=28; i<55; i++ )
tempkey[i]=tempkey[i+1];
tempkey[55]=temp;
}
}
//生成子密钥
void MakeSubKey(){
ChooseI();
for ( int i=0; i<16; i++){
ShiftL( i ) ;
ChooseSubKey( i ) ;
}
}
//plaintext:明文
//ciphertext: 密文
int plaintext[64] , ciphertext[64] , ans[64];
//初始置换IP的矩阵
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
};
typedef struct{
int num[32];
}PlainNum ;
PlainNum l[17],r[17];
int temp[48],s_temp[32];
//选择运算用的扩展矩阵
int expanper[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
};
//8个S盒
int s_box[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所用的矩阵
int permuted[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
};
/*初始置换IP*/
void Init_Per(){
for ( int i=0;i<32;i++)
l[0].num[i]=plaintext[ip[i]-1];
for ( int i=0;i<32;i++)
r[0].num[i]=plaintext[ip[i+32]-1];
}
/*解密的初始置换*/
void De_Per(){
for ( int i=0;i<32;i++)
r[0].num[i]=plaintext[ip[i]-1];
for ( int i=0;i<32;i++)
l[0].num[i]=plaintext[ip[i+32]-1];
}
/*选择运算E(Expansion Permutation)*/
void ExpanPer( int n ){
for ( int i=0;i<48;i++)
temp[i]=r[n-1].num[expanper[i]-1];
}
/*置换运算P*/
void Permute(){
for ( int i=0;i<32;i++)
temp[i]=s_temp[permuted[i]-1];
}
/*S盒运算SBOX*/
void SBOX(){
int row , col , svalue;
for ( int i=0;i<8;i++){
row=temp[i*6]*2+temp[i*6+5];
col=temp[i*6+1]*8+temp[i*6+2]*4+temp[i*6+3]*2+temp[i*6+4];
svalue=s_box[i][row][col];
s_temp[i*4]=svalue/8 ;
svalue %= 8;
s_temp[i*4+1]=svalue/4;
svalue %= 4;
s_temp[i*4+2]=svalue/2;
svalue %= 2;
s_temp[i*4+3]=svalue ;
}
}
/*加密函数*/
void EncryFunc( int n ){
for ( int i=0;i<32;i++)
l[n].num[i]=r[n-1].num[i];
for ( int i=0;i<48;i++)
temp[i]=r[n-1].num[expanper[i]-1];
for ( int i=0;i<48;i++)
temp[i] = temp[i]^subkey[n-1][i];
SBOX();
Permute();
for ( int i=0;i<32;i++)
r[n].num[i] = temp[i]^l[n-1].num[i];
}
/*解密函数*/
void DecryFunc( int n ){
for ( int i=0;i<48;i++)
temp[i]=l[n-1].num[expanper[i]-1];
for ( int i=0;i<48;i++)
temp[i] = temp[i]^subkey[16-n][i];
SBOX();
for ( int i=0;i<32;i++)
temp[i]=s_temp[permuted[i]-1];
for ( int i=0;i<32;i++)
r[n].num[i]=l[n-1].num[i];
for ( int i=0;i<32;i++)
l[n].num[i] = temp[i]^r[n-1].num[i];
}
/*逆初始置换IP-1*/
void IP_r(){
for ( int i=0;i<32;i++)
ans[i]=r[16].num[i];
for ( int i=0;i<32;i++)
ans[32+i]=l[16].num[i];
for ( int i=0;i<64;i++)
ciphertext[ip[i]-1]=ans[i];
}
/*解密的逆初始置换IP-1*/
void DIP_r(){
for ( int i=0;i<32;i++)
ans[i]=l[16].num[i];
for ( int i=0;i<32;i++)
ans[32+i]=r[16].num[i];
for ( int i=0;i<64;i++)
ciphertext[ip[i]-1]=ans[i];
}
/*加密过程*/
void Encryption(){
Init_Per( ) ;
for (int i=1;i<=16;i++)
EncryFunc( i ) ;
IP_r();
printf("得出的密文为: ");
for ( int i=0;i<64;i++)
printf("%d",ciphertext[i]);
printf(" ");
}
/*解密过程*/
void Decryption(){
De_Per();
for (int i=1;i<=16;i++)
DecryFunc( i ) ;
DIP_r();
printf("得出的明文为: ");
for ( int i=0;i<64;i++)
printf("%d",ciphertext[i]);
printf(" ");
}
char plain[100] , des_key[100];
int len_plain , len_key ;
int main(){
while (1){
printf("请选择 1 加密 2 解密: ");
scanf("%d",&choose);
switch (choose){
case 1 : printf("请输入明文: ");break;
case 2 : printf("请输入密文: ");break;
}
scanf("%s",plain);
printf("请输入密钥: ");
评论0