#include <iostream>
#include <fstream>
#include<string>
#include<memory>
using namespace std;
const static char IP[] = { //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
};
const static char inIP[] = { //逆初置换inip
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 SBox[8][4][16] = { //Sbox
// 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 PC_2[] = { //压缩置换,即置换选择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 E[] = { //扩展置换
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 PC_1[]={ //密钥置换表 keyrar置换选择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 P[]={ //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 shift[16]={ //左循环移动位数
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};
int change[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
void ByteToBit(bool *Out,char *In,int bits) //字节到位的转换
{
int i,j;
for(i=0;i<8;i++)
for(j=0; j<8; j++)
{
Out[8*i+j]=In[i]&change[j]; //转变成二进制
}
}
void BitToByte(char *Out,bool *In,int bits) //位到字节转换
{
int intout=0,i=0,j=0;
for(i=0;i<8;i++){
for(j=0;j<8;j++){
intout+=In[i*8+j]*change[j];
}
Out[i]=char(intout);
intout=0;
cout<<Out[i];
}
}
void Xor(bool *InA,const bool *InB,int bits) //按位异或
{
for(int i=0;i<bits;i++)
InA[i]^=InB[i];
}
bool key_turn[16][48];//轮密钥
void DES(char *In,char *Out,char *key)//,bool flag) //m为消息,c为密文, key为密钥
{
bool pm_Binary[64],m_Binary[64]; //消息二进制
bool pkey_Binary[64],key_Binary[56]; //密钥二进制
int i;
ByteToBit(pm_Binary,In,64); //消息转为二进制
ByteToBit(pkey_Binary,key,64); //密钥转为二进制
for(i=0;i<64;i++){
m_Binary[i]=pm_Binary[IP[i]-1]; //明文初始置换,注意减1
}
for(i=0;i<56; i++){
key_Binary[i]=pkey_Binary[PC_1[i]-1]; //密钥初始置换,即置换选择1
}
//轮函数
bool m_expand[48]; //扩展明文
//bool key_turn[16][48]; //轮密钥
bool key_temp[56]; //在轮函数中,暂时保存key
bool temp[64]; //保存明文
bool m_result[64]; //保存结果
int count=0;
while(count<16){ //循环16轮
for(i=0;i<64;i++){
temp[i] = m_Binary[i]; //temp暂存m_Binary
}
for(i=0;i<48;i++){
m_expand[i]=m_Binary[E[i]-1+32]; //明文扩展
}
for(i=0;i<56;i++){
key_temp[i] = key_Binary[i];
}
for(i=0;i<28;i++)
key_Binary[i]=key_temp[(i+shift[count])%28]; //密钥循环移位
for(i=28;i<56;i++)
key_Binary[i]=key_temp[(i+shift[count])%28+28];
for(i=0;i<48;i++){ //置换选择2
key_turn[count][i]=key_Binary[PC_2[i]-1];
}
Xor(m_expand,key_turn[count],48); //密钥与扩展后明文异或
bool s_temp[32];
for(i=0;i<8;i++){ //s盒操作
int row=m_expand[6*i]*2+m_expand[6*i+5];
int link=m_expand[6*i+1]*8+m_expand[6*i+2]*4+m_expand[6*i+3]*2+m_expand[6*i+4];
s_temp[i*4+3]=SBox[i][row][link]%2;
s_temp[i*4+2]=(SBox[i][row][link]/2)%2;
s_temp[i*4+1]=(SBox[i][row][link]/4)%2;
s_temp[i*4]=(SBox[i][row][link]/8)%2;
}
for(i=32;i<64;i++){
m_Binary[i]=s_temp[P[i-32]-1]; //P置换
}
for(i=0; i< 32; i++){
m_Binary[32+i]=m_Binary[32+i]^temp[i];
m_Binary[i]=temp[32+i]; //左右交换
}
count++;
}
//轮函数结束
bool t;
for(i=0;i<32;i++){ //左右交换
t=m_Binary[i];
m_Binary[i]=m_Binary[i+32];
m_Binary[32+i]=t;
}
for(i=0;i<64;i++){ //逆初始置换
m_result[i]=m_Binary[inIP[i]-1];
}
BitToByte(Out,m_result,64); //字节转换为字符
cout<<endl;
}
//bool m_expand[48]; //扩展明文
//bool key_turn[16][48];//轮密钥
void inDES(char *In,char *Out,char * key){//bool ming_Binary[64], char e_key[8]){mi ming
bool c_Binary[64];
bool temp[64];
bool m_expand[48]; //扩展明文
bool m_Binary[64];
int count = 15;
int i;
ByteToBit(c_Binary,In,64); //密文转为二进制
for(i=0;i<64;i++){
temp[i]=c_Binary[IP[i]-1];
}
for(i=0;i<64;i++){
c_Binary[i]=temp[i];
}
while(count>-1){
for(i=0;i<64;i++){
temp[i]=c_Binary[i];
}
for(i=0;i<48;i++){
m_expand[i]=c_Binary[E[i]-1+32];
}
Xor(m_expand,key_turn[count],48); //密钥与扩展后明文异或
bool s_temp[32];
for(i=0;i<8;i++){ //s盒操作
int row=m_expand[6*i]*2+m_expand[6*i+5];
int link=m_expand[6*i+1]*8+m_expand[6*i+2]*4+m_expand[6*i+3]*2+m_expand[6*i+4];
s_temp[i*4+3]=SBox[i][row][link]%2;
s_temp[i*4+2]=(SBox[i][row][link]/2)%2;
s_temp[i*4+1]=
评论0