代码放这留备份。
#include<iostream> #include<cstring> using namespace std; const static char S_Box[8][4][16] = { //S盒置换 // 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 }; const static char IP[64] = { //P置换 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 FP[64] = { //P逆置换 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 EP[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 }; const static char SP[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 }; const static char PC1[56] = { //置换选择1 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 }; const static char PC2[48] = { //置换选择2 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 LOOP[16]={ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 }; bool key[16][48]; void ByteToBit(char *In, bool *Out, int bits) //字节到位 { for(int i=0;i<bits;++i) Out[i] = (In[i/8]>>(i%8))&1; } void BitToByte(bool *In, char *Out, int bits) //位到字节 { memset(Out,0,bits/8); for(int i=0;i<bits;++i) Out[i/8] |= In[i]<<(i%8); } void Transform(bool *In, bool *Out, const char *Table, int len) //置换函数 { static bool temp[128]; for(int i=0; i<len; ++i) temp[i] = In[Table[i] - 1]; memcpy(Out,temp,len); } void CirculateMove(bool *In, int len,const char s) //循环左移 { static bool temp[128]; memcpy(temp, In, len); for(int i=0; i<len; ++i) In[i]=temp[(i+s)%len]; } void RoundKey(char initKey[8]) //计算轮密钥 { static bool keyBits[64], crypKeyBits[56]; ByteToBit(initKey, keyBits, 64); Transform(keyBits, crypKeyBits, PC1, 56); for(int i=0; i<16; ++i) { CirculateMove(crypKeyBits, 28, LOOP[i]); CirculateMove(&crypKeyBits[28], 28, LOOP[i]); Transform(crypKeyBits, key[i], PC2, 48); } } void Xor(bool *Out, bool *In, int len) ///异或运算 { for(int i=0; i<len; ++i) Out[i] ^= In[i]; } void S(bool In[48], bool Out[32]) //S盒替换 { int x, y; char c; for(int i=0; i<8; i++, In+=6) { x = In[0] * 2 + In[5]; y = In[1] * 8 + In[2] * 4 + In[3] * 2 + In[4]; c = S_Box[i][x][y]; Out[4*i] = (c%2)&1; Out[4*i+1] = ((c/2)%2)&1; Out[4*i+2] = ((c/4)%2)&1; Out[4*i+3] = ((c/8)%2)&1; } } void FE(bool In[64], bool thisKey[48]) //轮函数 { static bool temp[128],afterEP[48]; memcpy(temp,&In[32],32); Transform(&In[32], afterEP, EP, 48); Xor(afterEP,thisKey,48); S(afterEP,&In[32]); Transform(&In[32], &In[32], SP, 32); Xor(&In[32], In, 32); memcpy(In, temp, 32); } void FD(bool In[64], bool thisKey[48]) //轮函数 { static bool temp[128],afterEP[48]; memcpy(temp,In,32); Transform(In, afterEP, EP, 48); Xor(afterEP,thisKey,48); S(afterEP,In); Transform(In, In, SP, 32); Xor(In, &In[32], 32); memcpy(&In[32], temp, 32); } void Encrypt(char In[8], char Out[8]) //加密 { static bool bits[64]; ByteToBit(In,bits,64); Transform(bits,bits,IP,64); for(int i=0; i<16; ++i) FE(bits,key[i]); Transform(bits, bits, FP, 64); BitToByte(bits, Out, 64); } void Decrypt(char In[8], char Out[8]) //加密 { static bool bits[64]; ByteToBit(In,bits,64); Transform(bits,bits,IP,64); for(int i=15; i>=0; i--) FD(bits,key[i]); Transform(bits, bits, FP, 64); BitToByte(bits, Out, 64); } int main() { char c; char initKey[9]; cout<<"============= DES密码算法 =============="<<endl<<endl; cout<<"请设定8位字符的密钥:"<<endl; cin>>initKey; RoundKey(initKey); cin.get(c); char plainText[256],crypText[256],newPlainText[256]; cout<<endl<<"请输入要加密的明文(支持空格和中文):"<<endl; cin.getline(plainText,256); int l=strlen(plainText); if(l%8!=0) //如果长度不是8的倍数,以空格填充 { int newL = 8*(l/8+1); for(int i=l;i < newL;i++) plainText[i]=' '; } for(int i=0;i<l;i+=8) Encrypt(plainText+i,crypText+i); cout<<endl<<"您的明文加密后结果如下:"<<endl; for(int i=0;i<l;i++) cout<<crypText[i]; cout<<endl<<"-------------------------------------"<<endl; cout<<"请输入您之前设定的8位密钥来进行解密:"<<endl; cin>>initKey; RoundKey(initKey); for(int i=0;i<l;i+=8) Decrypt(crypText+i,newPlainText+i); cout<<endl<<"您的密文解密后结果如下:"<<endl; for(int i=0;i<l;i++) cout<<newPlainText[i]; cout<<endl<<endl<<"DES密码算法完成!"<<endl; system("pause"); return 0; }
时间: 2024-10-12 18:43:07