Des密码 C++实现

#include<iostream>
#include<vector>
#include<iterator>
#include<time.h>
#include<bitset>
#include<string>
#include<strstream>
using namespace std;

class Des
{

   public:
    void KeyBorn();                                             //产生密钥
       void Encrytion();                                           //加密函数
    void Decrytion();                                           //解密函数
       string S_Box(const bitset<48>&);                            //S盒子
    bitset<64> Share( const int (&)[64] );             //记载加密和解密函数的重复部分

   public:
    vector<int> cir_left ;
    vector<bitset<48> > vec_Key;
    char Choose_Modle ;
};

            //Share函数用来记载加密和解密函数的重复部分
bitset<64> Des::Share(const int (&origin_text)[64])     //用引用更好
{
 int first[] =  {origin_text[57],origin_text[49],origin_text[41],origin_text[33],origin_text[25],origin_text[17],origin_text[9],origin_text[1],\
              origin_text[59],origin_text[51],origin_text[43],origin_text[35],origin_text[27],origin_text[19],origin_text[11],origin_text[3],\
              origin_text[61],origin_text[53],origin_text[45],origin_text[37],origin_text[29],origin_text[21],origin_text[13],origin_text[5],\
              origin_text[63],origin_text[55],origin_text[47],origin_text[39],origin_text[31],origin_text[23],origin_text[15],origin_text[7],\
              origin_text[56],origin_text[48],origin_text[40],origin_text[32],origin_text[24],origin_text[16],origin_text[8],origin_text[0],\
              origin_text[58],origin_text[50],origin_text[42],origin_text[34],origin_text[26],origin_text[18],origin_text[10],origin_text[2],\
              origin_text[60],origin_text[52],origin_text[44],origin_text[36],origin_text[28],origin_text[20],origin_text[12],origin_text[4],\
               origin_text[62],origin_text[54],origin_text[46],origin_text[38],origin_text[30],origin_text[22],origin_text[14],origin_text[6] };
 bitset<32> L0 ;
 bitset<32> R0 ;
 for(int i = 0;i<32;i++) L0[i] = first[31-i];
 for( int i = 0;i<32;i++) R0[i] = first[63-i];
 //  cout<<L0<<endl<<R0;
 //  cout<<R0[0]<<R0[1]<<R0[2]<<endl;
 for( int j =0;j<16;j++)
 {
  int ch [] = {   R0[0],R0[31],R0[30],R0[29],R0[28],R0[27],\
               R0[28],R0[27],R0[26],R0[25],R0[24],R0[23],\
               R0[24],R0[23],R0[22],R0[21],R0[20],R0[19],\
               R0[20],R0[19],R0[18],R0[17],R0[16],R0[15],\
               R0[16],R0[15],R0[14],R0[13],R0[12],R0[11],\
               R0[12],R0[11],R0[10],R0[9],R0[8],R0[7],\
               R0[8],R0[7],R0[6],R0[5],R0[4],R0[3],\
               R0[4],R0[3],R0[2],R0[1],R0[0],R0[31]};
  bitset<48> Choose;                    //选择运算
  for(int i = 0 ;i<48;i++) Choose[i] = ch[47-i];       //对选择运算进行赋值

  bitset<48> K_Add_Ch;
  if('1'==Choose_Modle )  K_Add_Ch = vec_Key[j]^Choose ;    //将选择运算和子密钥进行异或,得到子密钥加
  if('2'==Choose_Modle )  K_Add_Ch = vec_Key[15-j]^Choose ;

  string str = S_Box(K_Add_Ch);
  bitset<32> S(str);
  bitset<32> P;                            //p置换
  int c[] = {S[16],S[25],S[12],S[11],\
   S[3],S[20],S[4],S[15],\
   S[31],S[17],S[9],S[6],\
   S[27],S[14],S[1],S[22],\
   S[30],S[24],S[8],S[18],\
   S[0],S[5],S[29],S[23],\
   S[13],S[19],S[2],S[26],\
   S[10],S[21],S[28],S[7]  };
  for(int i = 0 ;i<32;i++) P[i] = c[31-i];                //初始化P置换后的文件
  bitset<32> mid(R0);
  R0 = L0^P;
  L0 = mid;
 }
 bitset<32> m(R0);
 R0 = L0;
 L0 = m;
 //cout<<L0<<endl<<R0<<endl;    //验证
                                                                              //逆初始置换表
   int ni_fir[] = {R0[24],L0[24],R0[16],L0[16],R0[8],L0[8],R0[0],L0[0], \
             R0[25],L0[25],R0[17],L0[17],R0[9],L0[9],R0[1],L0[1],\
             R0[26],L0[26],R0[18],L0[18],R0[10],L0[10],R0[2],L0[2],\
                R0[27],L0[27],R0[19],L0[19],R0[11],L0[11],R0[3],L0[3],\
             R0[28],L0[28],R0[20],L0[20],R0[12],L0[12],R0[4],L0[4],\
             R0[29],L0[29],R0[21],L0[21],R0[13],L0[13],R0[5],L0[5],\
             R0[30],L0[30],R0[22],L0[22],R0[14],L0[14],R0[6],L0[6],\
             R0[30],L0[30],R0[23],L0[23],R0[15],L0[15],R0[7],L0[7] };
  bitset<64> result_text ;                                                       //输出加密或者是解密后的文件
  for(int i = 0 ;i<64;i++) result_text[i] = ni_fir[63-i];
  return result_text;                                                               //返回加密或者是解密后的文件
}
string Des::S_Box(const bitset<48>& k_ch)                                   //S盒子
{
 int S[8][4][16] = {                  //输入S盒
                     {{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}}\
                   };
 string change = "0000000100100011010001010110011110001001101010111100110111101111"; //用二进制表示0-15,这样在代替函数中可以直接加在字符串后面了
 vector<int> ivec;
 string s = "";
 for(int i = 7;i>=0;i--)
  {
   int a = k_ch[i * 6+5]*2 + k_ch[i * 6] ;
   int b = k_ch[i * 6 + 4]*8+ k_ch[i * 6 + 3]*4+ k_ch[i * 6 + 2]*2+ k_ch[i * 6 + 1];
   int k = S[7-i][a][b];
   s +=change.substr(k*4,4);
  }

  return s;

}

void Des::KeyBorn()
{
   int a[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1} ;
   copy(a,a+16,back_inserter(cir_left));
   int Key[] = {0,0,1,1,0,0,0,1,0,0,1,1,0,0,1,0,
             0,0,1,1,0,0,1,1,0,0,1,1,0,1,0,0,
                0,0,1,1,0,1,0,1,0,0,1,1,0,1,1,0,
                0,0,1,1,0,1,1,1,0,0,1,1,1,0,0,0 };
 //  srand(time(NULL));                                  //定义随机函数
 //  for(int i = 0;i<64;i++)    Key[i] = rand()%2;       //随即产生密钥
   int C[] = {Key[56],Key[48],Key[40],Key[32],Key[24],Key[16],Key[8],\
           Key[0],Key[57],Key[49],Key[41],Key[33],Key[25],Key[17],\
           Key[9],Key[1], Key[58],Key[50],Key[42],Key[34],Key[26], \
           Key[18],Key[10],Key[2],Key[59],Key[51],Key[43],Key[35]} ;
   bitset<28> C0 ;
   bitset<28> D0 ;
   bitset<48> bit_Key;

   for(int i = 0;i<28;i++)    C0[i] = (bool)C[27-i];                  //初始化C0

   int D[] = {Key[62],Key[54],Key[46],Key[38],Key[30],Key[22],Key[14],\
           Key[6],Key[61],Key[53],Key[45],Key[37],Key[29],Key[21],\
              Key[13], Key[5],Key[60],Key[52],Key[44],Key[36],Key[28],\
              Key[20],Key[12],Key[4],Key[27],Key[19],Key[11],Key[3]};
   for(int i = 0;i<28;i++)    D0[i] = D[27-i];                           //初始化D0

   for( int k = 0;k<16;k++)
   {

  int c1 = C0[27];
  int c2 = C0[26];
  int d1 = D0[27];
     int d2 = D0[26];

    C0 <<=(cir_left.at(k));                                   //由于左移后,末尾添加的是0,所以要把移走的数记载下来
    D0 <<=(cir_left.at(k));

    if(1==cir_left.at(k))
    {
     C0.set(0,c1);
     D0.set(0,d1);
    }
    if(2==cir_left.at(k))
    {
     C0.set(1,c1);
     D0.set(1,d1);
     C0.set(0,c2);
     D0.set(0,d2);
    }

//   cout<<C0<<endl<<D0<<endl;
    int K[] = {C0[14],C0[11],C0[17],C0[4],C0[27],C0[23],\
               C0[25],C0[0],C0[13],C0[22],C0[7],C0[18],\
               C0[5],C0[9],C0[16],C0[24],C0[2],C0[20],\
               C0[12],C0[21],C0[1],C0[8],C0[15],C0[26],\

               D0[15],D0[4],D0[25],D0[19],D0[9],D0[1],\
               D0[26],D0[16],D0[5],D0[11],D0[23],D0[8],\
               D0[12],D0[7],D0[17],D0[0],D0[22],D0[3],\
               D0[10],D0[14],D0[6],D0[20],D0[27],D0[24] };
    for(int j = 0;j<48;j++)    bit_Key[j] = K[47-j];
    vec_Key.push_back(bit_Key);                                     //将每次产生的密钥添加到向量中
   }
 /*
  vector<bitset<48> >::iterator it = vec_Key.begin();
   while(it != vec_Key.end())
   {
   cout<< (*it) << endl;

  it++;
   }
*/
}
 //加密函数
void Des::Encrytion()
{                                                           //输入明文
 int Plain[] = {0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,1,\
  0,0,1,1,0,0,1,0,0,0,1,1,0,0,1,1,\
  0,0,1,1,0,1,0,0,0,0,1,1,0,1,0,1,\
                0,0,1,1,0,1,1,0,0,0,1,1,0,1,1,1  };
                                                                              //初始置换
  bitset<64> Cipher_text(Share(Plain));
  cout<<"加密后的文件为: "<<Cipher_text<<endl;                                   //输入出加密后的文件

}
 //解密函数
void Des::Decrytion()
{                                                                //输入密文
 int Cipher[] = {1,0,0,0,1,0,1,1,1,0,1,1,0,1,0,0,\
              0,1,1,1,1,0,1,0,0,0,0,0,1,1,0,0,\
     1,1,1,1,0,0,0,0,1,0,1,0,1,0,0,1,\
     0,1,1,0,0,0,1,0,0,1,1,0,1,1,0,1 };

  bitset<64> plain_text(Share(Cipher)) ;
  cout<<"解密后的文件为: "<<plain_text<<endl;                                   //输入出加密后的文件


}

int main()

{
cout<<"/***************************Des加密 解密*************************************/"<<endl;

cout<<"请选择模式(1.加密 2.解密 3.退出程序)";
Des *d = new Des();
d->KeyBorn();               //生成密钥
InputModle :
cin>>d->Choose_Modle;
switch (d->Choose_Modle)
{
case '1' : d->Encrytion(); goto InputModle;
case '2' : d->Decrytion(); goto InputModle;
case '3' : return 0;
default : cout<<"您输入的不符合条件,请重选择模式:"<<endl; goto InputModle;
}
}

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值