//DES.h
#pragma once
#include "table.h"
#include <string>
#include <afx.h>
using namespace std;
class DES
{
public:
DES();//char *initialKey,char *data
void SetEncodeValue(char *initialKey,char *data);
void SetDecodeValue(char *initialKey,char *data);
void EncodeData(); //加密
void DecodeData(); //解密
virtual ~DES(){}
char* GetPlainData();
char* GetCipherData();
private:
void run(char Out[8],char In[8],bool MS); //ms=0 时加密,反之解密
void keyfc(); //获取密钥函数
void ByteToBit(char *Out,char *In,int bits); //字节到位的转换
void BitToByte(char *Out,char *In,int bits); //位到字节转换
void Xor(char *InA,const char *InB,int len); //按位异或
char key[16][48]; //轮密钥
char Ki[9]; //初始密钥
char plaindata[9]; //明文
char cipherdata[9]; //密文
};
//DES.cpp
#include "stdafx.h"
#include "DES.h"
DES::DES()
{
memset(Ki,0,sizeof(Ki));
memset(plaindata,0,sizeof(plaindata));
memset(cipherdata,0,sizeof(cipherdata));
for(int i = 0; i < 16; i++)
{
memset(key[i],0,sizeof(key[i]));
}
}
void DES::SetEncodeValue(char *initialKey,char *data)
{
memcpy(Ki,initialKey,strlen(initialKey));
Ki[strlen(initialKey)] = '\0';
memcpy(plaindata,data,strlen(data));
plaindata[strlen(data)] = '\0';
keyfc();
}
void DES::SetDecodeValue(char *initialKey,char *data)
{
memcpy(Ki,initialKey,strlen(initialKey));
Ki[strlen(initialKey)] = '\0';
memcpy(cipherdata,data,strlen(data));
cipherdata[strlen(data)] = '\0';
keyfc();
}
void DES::EncodeData()
{
run(cipherdata,plaindata,0);
}
void DES::DecodeData()
{
run(plaindata,cipherdata,1);
}
void DES::run(char Out[8],char In[8],bool MS)
{
char MW[64],tmp[32],PMW[64];
char kzmw[48],keytem[48],ss[32];
int hang,lie;
ByteToBit(PMW,In,64);
for(int j=0;j<64;j++)
{
MW[j]=PMW[ip[j]-1]; //初始置换
}
char *Li=&MW[0],*Ri=&MW[32];
for(int i=0;i<48;i++) //右明文扩展置换
kzmw[i]=Ri[ei[i]-1];
if(!MS) //DES加密过程
{
for(int lun=0;lun<16;lun++)
{
for(int i=0;i<32;i++)
ss[i]=Ri[i];
for(int i=0;i<48;i++) //右明文扩展置换
kzmw[i]=Ri[ei[i]-1];
for(int i=0;i<48;i++)
keytem[i]=key[lun][i]; //轮密钥
Xor(kzmw,keytem,48);
/*S盒置换*/
for(int 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]=sbox[i][(hang+1)*16+lie]%2;
tmp[i*4+2]=(sbox[i][(hang+1)*16+lie]/2)%2;
tmp[i*4+1]=(sbox[i][(hang+1)*16+lie]/4)%2;
tmp[i*4]=(sbox[i][(hang+1)*16+lie]/8)%2;
}
for(int i=0;i<32;i++) //P置换
Ri[i]=tmp[Pzh[i]-1];
Xor(Ri,Li,32); //异或
for(int i=0;i<32;i++) //交换左右明文
{
Li[i]=ss[i];
}
}
for(int i=0;i<32;i++)
{
tmp[i]=Li[i];
Li[i]=Ri[i];
Ri[i]=tmp[i];
}
for(int i=0;i<64;i++)
PMW[i]=MW[fp[i]-1];
BitToByte(Out,PMW,64); //位到字节的转换
}
else //DES解密过程
{
for(int lun=15;lun>=0;lun--)
{
for(int i=0;i<32;i++)
ss[i]=Ri[i];
for(int i=0;i<48;i++) //右明文扩展置换
kzmw[i]=Ri[ei[i]-1]; //注意指针
for(int i=0;i<48;i++)
keytem[i]=key[lun][i]; //轮密钥
Xor(kzmw,keytem,48);
/*S盒置换*/
for(int 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]=sbox[i][(hang+1)*16+lie]%2;
tmp[i*4+2]=(sbox[i][(hang+1)*16+lie]/2)%2;
tmp[i*4+1]=(sbox[i][(hang+1)*16+lie]/4)%2;
tmp[i*4]=(sbox[i][(hang+1)*16+lie]/8)%2;
}
for(int i=0;i<32;i++) //P置换
Ri[i]=tmp[Pzh[i]-1];
Xor(Ri,Li,32); //异或
for(int i=0;i<32;i++) //交换左右明文
{
Li[i]=ss[i];
}
}
for(int i=0;i<32;i++)
{
tmp[i]=Li[i];
Li[i]=Ri[i];
Ri[i]=tmp[i];
}
for(int i=0;i<64;i++)
PMW[i]=MW[fp[i]-1];
BitToByte(Out,PMW,64); //位到字节的转换
}
}
void DES::keyfc()
{
char key0[56],temp,keyin[64];
ByteToBit(keyin,Ki,64); //字节到位的转换
for(int i=0;i<56;i++) //密钥压缩为56位
key0[i]=keyin[Keyrar[i]-1];
for(int i=0;i<16;i++) //16轮密钥产生
{
int mov;
if(i==0||i==1||i==8||i==15)
mov=1;
else
mov=2;
for(int k=0;k<mov;k++) //分左右两块循环左移
{
for(int m=0;m<8;m++)
{
temp=key0[m*7];
for(int j=m*7;j<m*7+7;j++)
key0[j]=key0[j+1];
key0[m*7+6]=temp;
}
temp=key0[0];
for(int m=0;m<27;m++)
key0[m]=key0[m+1];
key0[27]=temp;
temp=key0[28];
for(int m=28;m<55;m++)
key0[m]=key0[m+1];
key0[55]=temp;
}
for(int j=0;j<48;j++) //压缩置换并储存
key[i][j]=key0[rar[j]-1];
}
}
void DES::BitToByte(char *Out,char *In,int bits)
{
for(int i=0;i<bits/8;i++)
Out[i]=0;
for(int i=0;i<bits;i++)
Out[i/8]|=In[i]<<(i%8);
}
void DES::ByteToBit(char *Out,char *In,int bits)
{
for(int i=0;i<bits;i++)
Out[i]=(In[i/8]>>(i%8))&1;
}
void DES::Xor(char *InA,const char *InB,int len)
{
for(int i=0;i<len;i++)
InA[i]^=InB[i];
}
char* DES::GetPlainData()
{
return plaindata;
}
char* DES::GetCipherData()
{
return cipherdata;
}