zoukankan      html  css  js  c++  java
  • 信息安全-简易的DES加解密--3DES

    在此感谢大佬:https://www.cnblogs.com/yinbiao/p/10460453.html 一步一步都有数据
    https://blog.csdn.net/lisonglisonglisong/article/details/41777413 按着这个大佬的思路来的

    #include<bits/stdc++.h>
    #define TLE ios::sync_with_stdio(0),cin.tie(0)
    using namespace std;
    bitset<64> bitencrypt;
    bitset<64> bitkey;
    bitset<64> bitdecrypt;
    bitset<48> keyarray[16];//48位!!!
    // 初始置换表
    int 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 };
    
    /*------------------下面是生成密钥所用表-----------------*/
    int PC_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};
    int PC_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};
    int shiftBits[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
    
    /*------------------轮函数-----------------*/
    // 扩展置换表,将32位扩展至48位
    int 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};
    // S盒,每个S盒是4x16的置换表,6位 -> 4位
    int S_BOX[8][4][16] = {
    	{
    		{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}
    	}
    };
    // P盒置换
    int 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 };
    /*--------------------------------------*/
    //初始逆置换
    int IP_1[] = {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};
    
    
    //===================================================
    void producekey(){
    //过程:64位密钥经置换选择1去除奇偶校验位变成56位 分开左右各28位
    //循环移位:第一轮L1左移一位+R1(共56位)经过压缩置换2成48位:key1
    //L1(28)继续左移一位:L2+R1(28):R2(共56位)经过压缩置换成48位:key2
    //L2(28)继续左移2位:L2+R1(28):R2(共56位)经过压缩置换成48位...
    //共移位16轮 每轮移位位数不同 所以直接拿数组存 到时候直接取
          bitset<56>trans1;
          bitset<28>left1,left2;
          bitset<28>right1,right2;
          bitset<56>trans2;
          bitset<48>trans3;
          for(int i=0;i<56;++i){//缩成56位:去除了奇偶校验位
            trans1[55-i] = bitkey[64-PC_1[i]];
          }
         // cout<<"producekey()--trans1: "<<trans1<<endl;
          //分左右
          for(int i=0;i<28;++i){
            right1[i] = trans1[i];
            left1[i] = trans1[i+28];
          }
          //cout<<"producekey()--right1: "<<right1<<endl;
          //cout<<"producekey()--left1: "<<left1<<endl;
          for(int round=0;round<16;round++){//一轮生成1个密钥(48)
                  if(shiftBits[round] == 1){
                    for(int i=27; i>0; i--){
                        //循环向左移位
                        left2[i]=left1[i-shiftBits[round]];
                        right2[i]=right1[i-shiftBits[round]];
                    }
                    left2[0] = left1[27];
                    right2[0] = right1[27];
                  }else{
                      for(int i=27; i>1; i--){
                        //循环向左移位
                        left2[i]=left1[i-shiftBits[round]];
                        right2[i]=right1[i-shiftBits[round]];
                     }
                      left2[1] = left1[27];left2[0] = left1[26];
                      right2[1] = right1[27];right2[0] = right1[26];
                  }
                  //cout<<"round: "<<round<<" left2: "<<left2<<endl;
                 // cout<<"round: "<<round<<" right2: "<<right2<<endl;
    
                  for(int i=0;i<28;i++){ //数组合并 这肯定不行啊trans2 = left2+right2;//28!!
                    trans2[i] = right2[i] ;
                    trans2[i+28] = left2[i];
                  }
                  //压缩置换成48位
                  for(int i=0;i<48;++i){
                    trans3[47-i] = trans2[56-PC_2[i]];
                  }
                  keyarray[round] = trans3;
                  //cout<<"producekey()--round: "<<round<<"  "<<keyarray[round]<<endl;
                  left1 = left2;
                  right1 = right2;
          }
    
    }
    int changetoten(string s){//二进制的字符串转成10进制的数字
    
        int a,m,b=0,k=0;
        //a = atoi(s);//string转int C++中若需要将string类型转为int类型,需先将string转为const char*。
        char c[100];strcpy(c,s.c_str());
        a = atoi(c);
        while(a!=0){
            m = a%10;
            a/=10;
            b+=m*pow(2,k++);
        }
        return b;
    
    }
    string changetotwo(int a){//10进制数字转成二进制字符串
           string s;
           int result = 0, temp = a, j = 1;
    	   while(temp){
    		  result = result + j * (temp % 2);
    		  temp = temp / 2;
    		  j = j * 10;
    	   }
           char t[256];
           sprintf(t, "%04d", result);//字符串位数不足高位补0
           s = t;
           return s;//都要经过中间商char数组
    }
    void encrypt(){ //得到64位密文
    
            bitset<64> trans1;
            bitset<32> left1;
            bitset<32> right1;
            bitset<32> temp;
            bitset<48> trans2;
            bitset<32> transsbox;
            bitset<32> transpbox;
            bitset<48> transleft;
            //NO1:初始置换IP 就是一个简单的for循环
            //cout<<"encrypt()--bitencrypt: "<<bitencrypt<<endl;
            for(int i=0;i<64;++i){
                trans1[63-i] = bitencrypt[64-IP[i]];
            }
            //cout<<"encrypt()--trans1: "<<trans1<<endl;
            //分成左右各32位的bitset
            for(int i=0;i<32;++i){
                right1[i] =trans1[i];
                left1[i] = trans1[i+32];//左右都要移位啊
            }
            //cout<<"encrypt()--left1: "<<left1<<endl;
           // cout<<"encrypt()--right1: "<<right1<<endl;
    
            //NO2:密钥整体的生成
            producekey();
            //回来了
            //N03:16轮轮函数
            for(int round=0;round<16;round++){//密钥key48位
    //过程:Li(32)位经位拓展表变成48位,和密钥key异或,再S盒[48位分成8个6位,每个6位输入S盒输出变成4位]32位
    //32位经P盒置换 输出置换后的32位==>Ri+1 Li+1==Ri
                 //cout<<"right1: "<<right1<<endl;
                 for(int i=0;i<48;++i){//轮函数no1:32位经E拓展成48位 ///48!!
                      transleft[47-i] = right1[32-E[i]];//拿R去做S盒
                 }
                 //cout<<"right2: "<<transleft<<endl;
                 //轮函数no2:和key异或
                 transleft = transleft^keyarray[round];
                 //cout<<"transleft: "<<transleft<<endl;
                 string strtransleft = transleft.to_string();
                 string middles1,middles2;
                 int row,column,resu;
                 //cout<<middles.length()<<endl;//48
                 for(int i=0;i<48;i+=6){//轮函数no3:S盒替代 48位变成32位
    //六位:首加末:行号 中间四位:列号 对应si盒找到该位置后用4位二进制表达
                       middles1 = strtransleft.substr(i,6);//起始位置 数目
                       string bemiddles1,mimiddles1;//清零
                       bemiddles1+=middles1[0];
                       bemiddles1+=middles1[5];
                       row = changetoten(bemiddles1);//string连接 什么烂毛病
                       mimiddles1+=middles1[1];
                       mimiddles1+=middles1[2];
                       mimiddles1+=middles1[3];
                       mimiddles1+=middles1[4];
                       column = changetoten(mimiddles1);//
                       resu = S_BOX[i/6][row][column];//i/6表面当前是哪个盒子
                       middles2.append(changetotwo(resu));
                       //每一轮结果:4位
                 }//middles2:32位str
                 //cout<<middles2.length()<<endl;长度不足32位
                 //cout<<"middles2: "<<middles2<<endl;
                 bitset<32> strtobit(middles2);
                 transsbox = strtobit;
                 //轮函数no4:P盒置换
                 for(int i=0;i<32;++i){
                     transpbox[31-i] = transsbox[32-P[i]];
                 }//f函数的输出
                 //Li=Ri-1  Ri=Li^f();
                 temp = right1;
                 right1=left1^transpbox;
                 left1 = temp;
    //             cout<<"left1: "<<left1<<endl;
    //             cout<<"right1: "<<right1<<endl;
            }
    
            //合并R16L16
            for(int i=0;i<32;++i){
                trans2[i] = left1[i];
                trans2[i+32] = right1[i];
            }
    
            //NO4:初始逆置换
            for(int i=0;i<64;++i){
                 bitdecrypt[63-i] = trans2[64-IP_1[i]];
            }
            cout<<"密文: "<<bitdecrypt<<endl;
    
    }
    
    void decrypt(){
    
            bitset<64> trans1;
            bitset<32> left1;
            bitset<32> right1;
            bitset<32> temp;
            bitset<48> trans2;
            bitset<32> transsbox;
            bitset<32> transpbox;
            bitset<48> transleft;
            //NO1:初始置换IP 就是一个简单的for循环
            //cout<<"encrypt()--bitencrypt: "<<bitencrypt<<endl;
            for(int i=0;i<64;++i){
                trans1[63-i] = bitdecrypt[64-IP[i]];//!!!!!!
            }
            //cout<<"encrypt()--trans1: "<<trans1<<endl;
            //分成左右各32位的bitset
            for(int i=0;i<32;++i){
                right1[i] =trans1[i];
                left1[i] = trans1[i+32];//左右都要移位啊
            }
            //cout<<"encrypt()--left1: "<<left1<<endl;
           // cout<<"encrypt()--right1: "<<right1<<endl;
    
            //NO2:密钥整体的生成
            producekey();
            //回来了
            //N03:16轮轮函数
            for(int round=0;round<16;round++){//密钥key48位
    //过程:Li(32)位经位拓展表变成48位,和密钥key异或,再S盒[48位分成8个6位,每个6位输入S盒输出变成4位]32位
    //32位经P盒置换 输出置换后的32位==>Ri+1 Li+1==Ri
                 //cout<<"right1: "<<right1<<endl;
                 for(int i=0;i<48;++i){//轮函数no1:32位经E拓展成48位 ///48!!
                      transleft[47-i] = right1[32-E[i]];//拿R去做S盒
                 }
                 //cout<<"right2: "<<transleft<<endl;
                 //轮函数no2:和key异或
                 transleft = transleft^keyarray[15-round];//!!!!
                 //cout<<"transleft: "<<transleft<<endl;
                 string strtransleft = transleft.to_string();
                 string middles1,middles2;
                 int row,column,resu;
                 //cout<<middles.length()<<endl;//48
                 for(int i=0;i<48;i+=6){//轮函数no3:S盒替代 48位变成32位
    //六位:首加末:行号 中间四位:列号 对应si盒找到该位置后用4位二进制表达
                       middles1 = strtransleft.substr(i,6);//起始位置 数目
                       string bemiddles1,mimiddles1;//清零
                       bemiddles1+=middles1[0];
                       bemiddles1+=middles1[5];
                       row = changetoten(bemiddles1);//string连接 什么烂毛病
                       mimiddles1+=middles1[1];
                       mimiddles1+=middles1[2];
                       mimiddles1+=middles1[3];
                       mimiddles1+=middles1[4];
                       column = changetoten(mimiddles1);//
                       resu = S_BOX[i/6][row][column];//i/6表面当前是哪个盒子
                       middles2.append(changetotwo(resu));
                       //每一轮结果:4位
                 }//middles2:32位str
                 //cout<<middles2.length()<<endl;长度不足32位
                 //cout<<"middles2: "<<middles2<<endl;
                 bitset<32> strtobit(middles2);
                 transsbox = strtobit;
                 //轮函数no4:P盒置换
                 for(int i=0;i<32;++i){
                     transpbox[31-i] = transsbox[32-P[i]];
                 }//f函数的输出
                 //Li=Ri-1  Ri=Li^f();
                 temp = right1;
                 right1=left1^transpbox;
                 left1 = temp;
    //             cout<<"left1: "<<left1<<endl;
    //             cout<<"right1: "<<right1<<endl;
            }
    
            //合并R16L16
            for(int i=0;i<32;++i){
                trans2[i] = left1[i];
                trans2[i+32] = right1[i];
            }
    
            //NO4:初始逆置换
            for(int i=0;i<64;++i){
                 bitencrypt[63-i] = trans2[64-IP_1[i]];
            }
            cout<<"明文: "<<bitencrypt<<endl;
    }
    
    
    int main(){
            TLE;
    
            string transsstr = "0000000100100011010001010110011110001001101010111100110111101111";
            string transmystr = "0001001100110100010101110111100110011011101111001101111111110001";
            bitset<64>bitencrypt1(transsstr);cout<<"明文: "<<bitencrypt1<<endl;//64位明文
            bitset<64>bitkey1(transmystr);cout<<"密钥: "<<bitkey1<<endl;//64位密钥
            bitencrypt = bitencrypt1;
            bitkey = bitkey1;
    
    
            //加密函数
            encrypt();
            //解密函数 跟加密函数
            decrypt();
    
    
            return 0;
    }
    

    其实很郁闷的是明明上周六就写好了 结果昨晚一看完全不是 只是不报错的版本 连做的word笔记都缺少了内容 不知道是怎么回事
    又花了一节课的时间缓缓改过来TT有点纳闷到底是怎么回事 每次都会保存的 别的朋友也不会动我的东西呀 就完全是订正前的样子 唉 于是先粘贴在这里吧
    开心的是S盒功能一次性写对了
    这是最初的版本 之后会在完善的

    进一步改善的3DES 还是不是很全面 但能实现8*n长度的string加解密 写入写出文件

    #include<bits/stdc++.h>
    #define TLE ios::sync_with_stdio(0),cin.tie(0)
    using namespace std;
    
    bitset<48> keyarray[16];
    // 初始置换表
    int 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 };
    
    /*------------------下面是生成密钥所用表-----------------*/
    int PC_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};
    int PC_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};
    int shiftBits[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
    
    /*------------------轮函数-----------------*/
    // 扩展置换表,将32位扩展至48位
    int 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};
    // S盒,每个S盒是4x16的置换表,6位 -> 4位
    int S_BOX[8][4][16] = {
    	{
    		{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}
    	}
    };
    // P盒置换
    int 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 };
    /*--------------------------------------*/
    //初始逆置换
    int IP_1[] = {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};
    
    
    //===================================================
    void producekey(bitset<64> bitkey){
    //过程:64位密钥经置换选择1去除奇偶校验位变成56位 分开左右各28位
    //循环移位:第一轮L1左移一位+R1(共56位)经过压缩置换2成48位:key1
    //L1(28)继续左移一位:L2+R1(28):R2(共56位)经过压缩置换成48位:key2
    //L2(28)继续左移2位:L2+R1(28):R2(共56位)经过压缩置换成48位...
    //共移位16轮 每轮移位位数不同 所以直接拿数组存 到时候直接取
          bitset<56>trans1;
          bitset<28>left1,left2;
          bitset<28>right1,right2;
          bitset<56>trans2;
          bitset<48>trans3;
          for(int i=0;i<56;++i){//缩成56位:去除了奇偶校验位
            trans1[55-i] = bitkey[64-PC_1[i]];
          }
         // cout<<"producekey()--trans1: "<<trans1<<endl;
          //分左右
          for(int i=0;i<28;++i){
            right1[i] = trans1[i];
            left1[i] = trans1[i+28];
          }
          //cout<<"producekey()--right1: "<<right1<<endl;
          //cout<<"producekey()--left1: "<<left1<<endl;
          for(int round=0;round<16;round++){//一轮生成1个密钥(48)
                  if(shiftBits[round] == 1){
                    for(int i=27; i>0; i--){
                        //循环向左移位
                        left2[i]=left1[i-shiftBits[round]];
                        right2[i]=right1[i-shiftBits[round]];
                    }
                    left2[0] = left1[27];
                    right2[0] = right1[27];
                  }else{
                      for(int i=27; i>1; i--){
                        //循环向左移位
                        left2[i]=left1[i-shiftBits[round]];
                        right2[i]=right1[i-shiftBits[round]];
                     }
                      left2[1] = left1[27];left2[0] = left1[26];
                      right2[1] = right1[27];right2[0] = right1[26];
                  }
                  //cout<<"round: "<<round<<" left2: "<<left2<<endl;
                 // cout<<"round: "<<round<<" right2: "<<right2<<endl;
    
                  for(int i=0;i<28;i++){ //数组合并 这肯定不行啊trans2 = left2+right2;//28!!
                    trans2[i] = right2[i] ;
                    trans2[i+28] = left2[i];
                  }
                  //压缩置换成48位
                  for(int i=0;i<48;++i){
                    trans3[47-i] = trans2[56-PC_2[i]];
                  }
                  keyarray[round] = trans3;
                  //cout<<"producekey()--round: "<<round<<"  "<<keyarray[round]<<endl;
                  left1 = left2;
                  right1 = right2;
          }
    
    }
    int changetoten(string s){//二进制的字符串转成10进制的数字
    
        int a,m,b=0,k=0;
        //a = atoi(s);//string转int C++中若需要将string类型转为int类型,需先将string转为const char*。
        char c[100];strcpy(c,s.c_str());
        a = atoi(c);
        while(a!=0){
            m = a%10;
            a/=10;
            b+=m*pow(2,k++);
        }
        return b;
    }
    string changetotwo(int a){//10进制数字转成二进制字符串
           string s;
           int result = 0, temp = a, j = 1;
    	   while(temp){
    		  result = result + j * (temp % 2);
    		  temp = temp / 2;
    		  j = j * 10;
    	   }
           char t[256];
           sprintf(t, "%04d", result);//字符串位数不足高位补0
           s = t;
           return s;//都要经过中间商char数组
    }
    string encrypt(bitset<64>bitkey,string strwen){ //参数得是64位bitset明文 返回64位密文
            bitset<64> bitencrypt(strwen);
            bitset<64> bitdecrypt;
    
            bitset<64> trans1;
            bitset<32> left1;
            bitset<32> right1;
            bitset<32> temp;
            bitset<48> trans2;
            bitset<32> transsbox;
            bitset<32> transpbox;
            bitset<48> transleft;
            for(int i=0;i<64;++i){
                trans1[63-i] = bitencrypt[64-IP[i]];
            }
            for(int i=0;i<32;++i){
                right1[i] =trans1[i];
                left1[i] = trans1[i+32];
            }
            //NO2:密钥整体的生成
            producekey(bitkey);
            //回来了
            for(int round=0;round<16;round++){
                 for(int i=0;i<48;++i){
                      transleft[47-i] = right1[32-E[i]];
                 }
                 transleft = transleft^keyarray[round];
                 string strtransleft = transleft.to_string();
                 string middles1,middles2;
                 int row,column,resu;
                 for(int i=0;i<48;i+=6){
                       middles1 = strtransleft.substr(i,6);
                       string bemiddles1,mimiddles1;
                       bemiddles1+=middles1[0];
                       bemiddles1+=middles1[5];
                       row = changetoten(bemiddles1);
                       mimiddles1+=middles1[1];
                       mimiddles1+=middles1[2];
                       mimiddles1+=middles1[3];
                       mimiddles1+=middles1[4];
                       column = changetoten(mimiddles1);
                       resu = S_BOX[i/6][row][column];
                       middles2.append(changetotwo(resu));
                 }
                 bitset<32> strtobit(middles2);
                 transsbox = strtobit;
                 for(int i=0;i<32;++i){
                     transpbox[31-i] = transsbox[32-P[i]];
                 }
                 temp = right1;
                 right1=left1^transpbox;
                 left1 = temp;
            }
            for(int i=0;i<32;++i){
                trans2[i] = left1[i];
                trans2[i+32] = right1[i];
            }
            for(int i=0;i<64;++i){
                 bitdecrypt[63-i] = trans2[64-IP_1[i]];
            }
            cout<<"encrypt()---密文: "<<bitdecrypt<<endl;
            return bitdecrypt.to_string();//转成64位二进制字符串
    
    
    }
    
    string decrypt(bitset<64>bitkey,string strwen){
            bitset<64> bitencrypt;
            bitset<64> bitdecrypt(strwen);
    
            bitset<64> trans1;
            bitset<32> left1;
            bitset<32> right1;
            bitset<32> temp;
            bitset<48> trans2;
            bitset<32> transsbox;
            bitset<32> transpbox;
            bitset<48> transleft;
            for(int i=0;i<64;++i){
                trans1[63-i] = bitdecrypt[64-IP[i]];
            }
            for(int i=0;i<32;++i){
                right1[i] =trans1[i];
                left1[i] = trans1[i+32];
            }
            //NO2:密钥整体的生成
            producekey(bitkey);
    
            for(int round=0;round<16;round++){
                 for(int i=0;i<48;++i){
                      transleft[47-i] = right1[32-E[i]];
                 }
                 transleft = transleft^keyarray[15-round];
                 string strtransleft = transleft.to_string();
                 string middles1,middles2;
                 int row,column,resu;
                 for(int i=0;i<48;i+=6){
                       middles1 = strtransleft.substr(i,6);
                       string bemiddles1,mimiddles1;
                       bemiddles1+=middles1[0];
                       bemiddles1+=middles1[5];
                       row = changetoten(bemiddles1);
                       mimiddles1+=middles1[1];
                       mimiddles1+=middles1[2];
                       mimiddles1+=middles1[3];
                       mimiddles1+=middles1[4];
                       column = changetoten(mimiddles1);
                       resu = S_BOX[i/6][row][column];
                       middles2.append(changetotwo(resu));
                 }
                 bitset<32> strtobit(middles2);
                 transsbox = strtobit;
                 for(int i=0;i<32;++i){
                     transpbox[31-i] = transsbox[32-P[i]];
                 }
                 temp = right1;
                 right1=left1^transpbox;
                 left1 = temp;
            }
            for(int i=0;i<32;++i){
                trans2[i] = left1[i];
                trans2[i+32] = right1[i];
            }
            for(int i=0;i<64;++i){
                 bitencrypt[63-i] = trans2[64-IP_1[i]];
            }
            cout<<"decrypt()--明文: "<<bitencrypt<<endl;
            return bitencrypt.to_string();//转成64位二进制字符串
    }
    
    string stringtotwo(string str){//字符转二进制 一个字符转8位二进制  这里改  改成字符串的
          unsigned char k=0x80;//https://blog.csdn.net/caiyaodeng/article/details/48998469
          string transsstr;
          //string转char*
          const char *schar = str.c_str();
          for(int i=0;i<strlen(schar);++i){
            unsigned char k=0x80;
            for(int j=0; j<8; j++, k >>= 1){
                if (schar[i]&k){
                    transsstr.append("1");
                }else{
                    transsstr.append("0");
                }
            }
         }
         return transsstr;
    }
    
    string convert(char p[]){ //16进制转成文本
        int i=0;
        while(p[2*i]!=''&&p[2*i+1]!='')//'' :ASCII码为0,表示一个字符串结束的标志
        {
            char c = p[2*i];
            if(c<='9')
              p[i] = (c-'0')<<4;
            else if(c<='F')
              p[i] = (c-'A'+10)<<4;
            else
              p[i] = (c-'a'+10)<<4;
            c = p[2*i+1];
            if(c<='9')
              p[i] += (c-'0');
            else if(c<='F')
              p[i] += (c-'A'+10);
            else
              p[i] += (c-'a'+10);
            i++;
        }
        p[i] = '';
        return p;
    }
    string totwostring(string str){ //32位二进制转成string
        string binary = str;
        string hex;
        stringstream ss;
        ss << std::hex << stoi(binary, nullptr, 2);//https://www.cnblogs.com/tsruixi/p/12944470.html
        ss >> hex;
        transform(hex.begin(), hex.end(), hex.begin(), ::toupper);//将某操作应用于指定范围的每个元素
        cout << hex <<endl;
        char a[100];
        strcpy(a,hex.c_str());
        return convert(a);
    }
    string process1(string mingw,int quesizezz){//该函数对这段64位明文 返回二进制的string密文
    
        string mystr3[3] = {"11223344","22334455","33445566"};
        string mytwo[3] = {"","",""};
        for(int z=0;z<3;z++){
            mytwo[z] = stringtotwo(mystr3[z]);
        }
        bitset<64>bitkey11(mytwo[0]);//用string初始化
        bitset<64>bitkey22(mytwo[1]);
        bitset<64>bitkey33(mytwo[2]);//k1 k2 k3
    
        bitset<64>one(encrypt(bitkey33,decrypt(bitkey22,encrypt(bitkey11,mingw))));//加密过程 得到64位密文
        cout<<"process1--one"<<endl;
        return one.to_string();
    }
    string process2(string mew,int quesizezz){//该函数对这段64位密文 返回二进制的string明文
        cout<<"process2--mew: "<<mew<<endl;
        string mystr3[3] = {"11223344","22334455","33445566"};
        string mytwo[3] = {"","",""};
        for(int z=0;z<3;z++){
            mytwo[z] = stringtotwo(mystr3[z]);
        }
        bitset<64>bitkey11(mytwo[0]);
        bitset<64>bitkey22(mytwo[1]);
        bitset<64>bitkey33(mytwo[2]);
    
        bitset<64>one(decrypt(bitkey11,encrypt(bitkey22,decrypt(bitkey33,mew))));//解密过程 得到64位明文
        cout<<"process2--one"<<endl;
        return one.to_string();
    }
    int main(){
            TLE;
            ofstream out1("ciphertext.txt");
            ofstream out2("later.txt");//写
    
            string returnmew;
            string returnmingw;
    
            //读明文文件 并补足 并分组
            ifstream in;
            in.open("former.txt");
            if(!in.is_open()){
                cerr<<"could not open this file"<<endl;
                exit(0);
            }
            char ch;
            string mingw;
            while(in.get(ch)){
                mingw.push_back(ch);
            }
            in.close();
            cout<<"mingw1: "<<mingw<<endl;
            mingw = stringtotwo(mingw);
            cout<<"mingw2: "<<mingw<<" mingw2.size(): "<<mingw.size()<<endl;
            int quesize = 64-(mingw.size()%64);
            int i=0;
            if(quesize==64){//证明不缺
                 quesize = 0;
            }else{
                while(i < quesize){
                    mingw += '0';
                    i++;
                }
            }
            //mingw:有足够64倍数位的二进制string
    
    
            for(i=0;i<mingw.size();i=i+64){
                string s64 = mingw.substr(i,64);//每次都截取64位
                if(i == (mingw.size()-63)){//判断得出这是最后一组64位
    //               returnmew = process1(s64,quesize);//证明后面补0了 mew不足64位
    //                //删去补足的位数 写入文件
    //                //再进行解密 密文还得是64位啊 翻译回来的明文也是64位 可对应的明文位数明明不是64位的
    //               returnmingw =  process2(mew,quesize);
    //               returnmingw = totwostring(returnming);
                     cout<<"最后一组"<<endl;
                }else{ //正常的64位
                    cout<<"正常的64位"<<endl;
                    returnmew = process1(s64,0);
                    cout<<"returnmew: "<<returnmew<<endl;
                    //写入加密文件
                    if (out1.is_open()) {
                        out1<<returnmew;
                    }
                    //这里不安排读了 传回来的参数直接给process2函数
                    //再进行解密
                   returnmingw = process2(returnmew,0);//64位string二进制 转成字符串
                   returnmingw = totwostring(returnmingw.substr(0,32)) + totwostring(returnmingw.substr(32,32));
                   //写入解密文件:
                   if (out2.is_open()) {
                        out2<<returnmingw;
                   }
                }
            }
            out1.close();
            out2.close();
    
            return 0;
    }
    
    

    二进制转string 困扰了我很久妈蛋

    #include<bits/stdc++.h>
    using namespace std;
    
    string convert(char p[]){ //16进制转成文本
        int i=0;
        while(p[2*i]!=''&&p[2*i+1]!='')//'' :ASCII码为0,表示一个字符串结束的标志
        {
            char c = p[2*i];
            if(c<='9')
              p[i] = (c-'0')<<4;
            else if(c<='F')
              p[i] = (c-'A'+10)<<4;
            else
              p[i] = (c-'a'+10)<<4;
            c = p[2*i+1];
            if(c<='9')
              p[i] += (c-'0');
            else if(c<='F')
              p[i] += (c-'A'+10);
            else
              p[i] += (c-'a'+10);
            i++;
        }
        p[i] = '';
        return p;
    }
    string totwostring(string str){ //64位二进制转成string
        string binary = str;
        string hex;
        stringstream ss;
        ss << std::hex << stoi(binary, nullptr, 2);//https://www.cnblogs.com/tsruixi/p/12944470.html
        ss >> hex;
        transform(hex.begin(), hex.end(), hex.begin(), ::toupper);//将某操作应用于指定范围的每个元素
        cout << hex <<endl;
        char a[100];
        strcpy(a,hex.c_str());
        return convert(a);
    }
    int main()
    {  
    
         string s1 = "0111001001101111011011010110000101101110011101000110100101100011";
         cout<<totwostring(s1.substr(0,32))<<endl;
         cout<<totwostring(s1.substr(32,32))<<endl;
         s1 = totwostring(s1.substr(0,32)) + totwostring(s1.substr(32,32));
         cout<<s1<<endl;
    }
    
    

    上面函数无法处理多位数据 所以分开了

    #include<bits/stdc++.h>
    #define TLE ios::sync_with_stdio(0),cin.tie(0)
    using namespace std;
    
    bitset<48> keyarray[16];
    // 初始置换表
    int 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 };
    
    /*------------------下面是生成密钥所用表-----------------*/
    int PC_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};
    int PC_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};
    int shiftBits[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
    
    /*------------------轮函数-----------------*/
    // 扩展置换表,将32位扩展至48位
    int 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};
    // S盒,每个S盒是4x16的置换表,6位 -> 4位
    int S_BOX[8][4][16] = {
    	{
    		{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}
    	}
    };
    // P盒置换
    int 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 };
    /*--------------------------------------*/
    //初始逆置换
    int IP_1[] = {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};
    
    
    //===================================================
    void producekey(bitset<64> bitkey){
    //过程:64位密钥经置换选择1去除奇偶校验位变成56位 分开左右各28位
    //循环移位:第一轮L1左移一位+R1(共56位)经过压缩置换2成48位:key1
    //L1(28)继续左移一位:L2+R1(28):R2(共56位)经过压缩置换成48位:key2
    //L2(28)继续左移2位:L2+R1(28):R2(共56位)经过压缩置换成48位...
    //共移位16轮 每轮移位位数不同 所以直接拿数组存 到时候直接取
          bitset<56>trans1;
          bitset<28>left1,left2;
          bitset<28>right1,right2;
          bitset<56>trans2;
          bitset<48>trans3;
          for(int i=0;i<56;++i){//缩成56位:去除了奇偶校验位
            trans1[55-i] = bitkey[64-PC_1[i]];
          }
         // cout<<"producekey()--trans1: "<<trans1<<endl;
          //分左右
          for(int i=0;i<28;++i){
            right1[i] = trans1[i];
            left1[i] = trans1[i+28];
          }
          //cout<<"producekey()--right1: "<<right1<<endl;
          //cout<<"producekey()--left1: "<<left1<<endl;
          for(int round=0;round<16;round++){//一轮生成1个密钥(48)
                  if(shiftBits[round] == 1){
                    for(int i=27; i>0; i--){
                        //循环向左移位
                        left2[i]=left1[i-shiftBits[round]];
                        right2[i]=right1[i-shiftBits[round]];
                    }
                    left2[0] = left1[27];
                    right2[0] = right1[27];
                  }else{
                      for(int i=27; i>1; i--){
                        //循环向左移位
                        left2[i]=left1[i-shiftBits[round]];
                        right2[i]=right1[i-shiftBits[round]];
                     }
                      left2[1] = left1[27];left2[0] = left1[26];
                      right2[1] = right1[27];right2[0] = right1[26];
                  }
                  //cout<<"round: "<<round<<" left2: "<<left2<<endl;
                 // cout<<"round: "<<round<<" right2: "<<right2<<endl;
    
                  for(int i=0;i<28;i++){ //数组合并 这肯定不行啊trans2 = left2+right2;//28!!
                    trans2[i] = right2[i] ;
                    trans2[i+28] = left2[i];
                  }
                  //压缩置换成48位
                  for(int i=0;i<48;++i){
                    trans3[47-i] = trans2[56-PC_2[i]];
                  }
                  keyarray[round] = trans3;
                  //cout<<"producekey()--round: "<<round<<"  "<<keyarray[round]<<endl;
                  left1 = left2;
                  right1 = right2;
          }
    
    }
    int changetoten(string s){//二进制的字符串转成10进制的数字
    
        int a,m,b=0,k=0;
        //a = atoi(s);//string转int C++中若需要将string类型转为int类型,需先将string转为const char*。
        char c[100];strcpy(c,s.c_str());
        a = atoi(c);
        while(a!=0){
            m = a%10;
            a/=10;
            b+=m*pow(2,k++);
        }
        return b;
    }
    string changetotwo(int a){//10进制数字转成二进制字符串
           string s;
           int result = 0, temp = a, j = 1;
    	   while(temp){
    		  result = result + j * (temp % 2);
    		  temp = temp / 2;
    		  j = j * 10;
    	   }
           char t[256];
           sprintf(t, "%04d", result);//字符串位数不足高位补0
           s = t;
           return s;//都要经过中间商char数组
    }
    string encrypt(bitset<64>bitkey,string strwen){ //参数得是64位bitset明文 返回64位密文
            bitset<64> bitencrypt(strwen);
            bitset<64> bitdecrypt;
    
            bitset<64> trans1;
            bitset<32> left1;
            bitset<32> right1;
            bitset<32> temp;
            bitset<48> trans2;
            bitset<32> transsbox;
            bitset<32> transpbox;
            bitset<48> transleft;
            for(int i=0;i<64;++i){
                trans1[63-i] = bitencrypt[64-IP[i]];
            }
            for(int i=0;i<32;++i){
                right1[i] =trans1[i];
                left1[i] = trans1[i+32];
            }
            //NO2:密钥整体的生成
            producekey(bitkey);
            //回来了
            for(int round=0;round<16;round++){
                 for(int i=0;i<48;++i){
                      transleft[47-i] = right1[32-E[i]];
                 }
                 transleft = transleft^keyarray[round];
                 string strtransleft = transleft.to_string();
                 string middles1,middles2;
                 int row,column,resu;
                 for(int i=0;i<48;i+=6){
                       middles1 = strtransleft.substr(i,6);
                       string bemiddles1,mimiddles1;
                       bemiddles1+=middles1[0];
                       bemiddles1+=middles1[5];
                       row = changetoten(bemiddles1);
                       mimiddles1+=middles1[1];
                       mimiddles1+=middles1[2];
                       mimiddles1+=middles1[3];
                       mimiddles1+=middles1[4];
                       column = changetoten(mimiddles1);
                       resu = S_BOX[i/6][row][column];
                       middles2.append(changetotwo(resu));
                 }
                 bitset<32> strtobit(middles2);
                 transsbox = strtobit;
                 for(int i=0;i<32;++i){
                     transpbox[31-i] = transsbox[32-P[i]];
                 }
                 temp = right1;
                 right1=left1^transpbox;
                 left1 = temp;
            }
            for(int i=0;i<32;++i){
                trans2[i] = left1[i];
                trans2[i+32] = right1[i];
            }
            for(int i=0;i<64;++i){
                 bitdecrypt[63-i] = trans2[64-IP_1[i]];
            }
            cout<<"encrypt()---密文: "<<bitdecrypt<<endl;
            return bitdecrypt.to_string();//转成64位二进制字符串
    
    
    }
    
    string decrypt(bitset<64>bitkey,string strwen){
            bitset<64> bitencrypt;
            bitset<64> bitdecrypt(strwen);
    
            bitset<64> trans1;
            bitset<32> left1;
            bitset<32> right1;
            bitset<32> temp;
            bitset<48> trans2;
            bitset<32> transsbox;
            bitset<32> transpbox;
            bitset<48> transleft;
            for(int i=0;i<64;++i){
                trans1[63-i] = bitdecrypt[64-IP[i]];
            }
            for(int i=0;i<32;++i){
                right1[i] =trans1[i];
                left1[i] = trans1[i+32];
            }
            //NO2:密钥整体的生成
            producekey(bitkey);
    
            for(int round=0;round<16;round++){
                 for(int i=0;i<48;++i){
                      transleft[47-i] = right1[32-E[i]];
                 }
                 transleft = transleft^keyarray[15-round];
                 string strtransleft = transleft.to_string();
                 string middles1,middles2;
                 int row,column,resu;
                 for(int i=0;i<48;i+=6){
                       middles1 = strtransleft.substr(i,6);
                       string bemiddles1,mimiddles1;
                       bemiddles1+=middles1[0];
                       bemiddles1+=middles1[5];
                       row = changetoten(bemiddles1);
                       mimiddles1+=middles1[1];
                       mimiddles1+=middles1[2];
                       mimiddles1+=middles1[3];
                       mimiddles1+=middles1[4];
                       column = changetoten(mimiddles1);
                       resu = S_BOX[i/6][row][column];
                       middles2.append(changetotwo(resu));
                 }
                 bitset<32> strtobit(middles2);
                 transsbox = strtobit;
                 for(int i=0;i<32;++i){
                     transpbox[31-i] = transsbox[32-P[i]];
                 }
                 temp = right1;
                 right1=left1^transpbox;
                 left1 = temp;
            }
            for(int i=0;i<32;++i){
                trans2[i] = left1[i];
                trans2[i+32] = right1[i];
            }
            for(int i=0;i<64;++i){
                 bitencrypt[63-i] = trans2[64-IP_1[i]];
            }
            cout<<"decrypt()--明文: "<<bitencrypt<<endl;
            return bitencrypt.to_string();//转成64位二进制字符串
    }
    
    string stringtotwo(string str){//字符转二进制 一个字符转8位二进制  这里改  改成字符串的
          unsigned char k=0x80;//https://blog.csdn.net/caiyaodeng/article/details/48998469
          string transsstr;
          //string转char*
          const char *schar = str.c_str();
          for(int i=0;i<strlen(schar);++i){
            unsigned char k=0x80;
            for(int j=0; j<8; j++, k >>= 1){
                if (schar[i]&k){
                    transsstr.append("1");
                }else{
                    transsstr.append("0");
                }
            }
         }
         return transsstr;
    }
    
    string convert(char p[]){ //16进制转成文本
        int i=0;
        while(p[2*i]!=''&&p[2*i+1]!='')//'' :ASCII码为0,表示一个字符串结束的标志
        {
            char c = p[2*i];
            if(c<='9')
              p[i] = (c-'0')<<4;
            else if(c<='F')
              p[i] = (c-'A'+10)<<4;
            else
              p[i] = (c-'a'+10)<<4;
            c = p[2*i+1];
            if(c<='9')
              p[i] += (c-'0');
            else if(c<='F')
              p[i] += (c-'A'+10);
            else
              p[i] += (c-'a'+10);
            i++;
        }
        p[i] = '';
        return p;
    }
    string totwostring(string str){ //32位二进制转成string
        string binary = str;
        string hex;
        stringstream ss;
        ss << std::hex << stoi(binary, nullptr, 2);//https://www.cnblogs.com/tsruixi/p/12944470.html
        ss >> hex;
        transform(hex.begin(), hex.end(), hex.begin(), ::toupper);//将某操作应用于指定范围的每个元素
        char a[100];
        strcpy(a,hex.c_str());
        return convert(a);
    }
    string process1(string mingw,int quesizezz){//该函数对这段64位明文 返回二进制的string密文
    
        string mystr3[3] = {"11223344","22334455","33445566"};
        string mytwo[3] = {"","",""};
        for(int z=0;z<3;z++){
            mytwo[z] = stringtotwo(mystr3[z]);
        }
        bitset<64>bitkey11(mytwo[0]);//用string初始化
        bitset<64>bitkey22(mytwo[1]);
        bitset<64>bitkey33(mytwo[2]);//k1 k2 k3
    
        bitset<64>one(encrypt(bitkey33,decrypt(bitkey22,encrypt(bitkey11,mingw))));//加密过程 得到64位密文
        return one.to_string();
    }
    string process2(string mew,int quesizezz){//该函数对这段64位密文 返回二进制的string明文
    
        string mystr3[3] = {"11223344","22334455","33445566"};
        string mytwo[3] = {"","",""};
        for(int z=0;z<3;z++){
            mytwo[z] = stringtotwo(mystr3[z]);
        }
        bitset<64>bitkey11(mytwo[0]);
        bitset<64>bitkey22(mytwo[1]);
        bitset<64>bitkey33(mytwo[2]);
    
        bitset<64>one(decrypt(bitkey11,encrypt(bitkey22,decrypt(bitkey33,mew))));//解密过程 得到64位明文
        return one.to_string();
    }
    int main(){
            TLE;
            ofstream out1("ciphertext.txt");
            ofstream out2("later.txt");//写
    
            string returnmew;
            string returnmingw;
    
            //读明文文件 并补足 并分组
            ifstream in;
            in.open("former.txt");
            if(!in.is_open()){
                cerr<<"could not open this file"<<endl;
                exit(0);
            }
            char ch;
            string mingw;
            while(in.get(ch)){
                mingw.push_back(ch);
            }
            in.close();
            cout<<"mingw1: "<<mingw<<endl;
            mingw = stringtotwo(mingw);
            cout<<"mingw2: "<<mingw<<" mingw2.size(): "<<mingw.size()<<endl;
            int quesize = 64-(mingw.size()%64);
            cout<<"quesize: "<<quesize<<endl;
            int i=0;
            if(quesize==64){//证明不缺
                 quesize = 0;
            }else{
                while(i < quesize){
                    mingw += '0';
                    i++;
                }
            }
            cout<<"mingw: "<<mingw<<endl;
            //mingw:有足够64倍数位的二进制string
    
            for(i=0;i<mingw.size();i=i+64){
                string s64 = mingw.substr(i,64);
                if((i == (mingw.size()-64)) && (quesize!=0)){//判断得出这是有缺失的最后一组64位
                   cout<<"最后一组且有缺失"<<endl;
                   cout<<"quesize: "<<quesize<<endl;
                   returnmew = process1(s64,quesize);//证明后面补0了
                    if (out1.is_open()) {
                        out1<<returnmew;
                    }
                   returnmingw = process2(returnmew,quesize);
                   returnmingw = totwostring(returnmingw.substr(0,32)) + totwostring(returnmingw.substr(32,32));
                   if (out2.is_open()) {
                        out2<<returnmingw;
                   }
                }else{
                    cout<<"正常的64位"<<endl;
                    returnmew = process1(s64,0);
                    if (out1.is_open()) {
                        out1<<returnmew;
                    }
                   returnmingw = process2(returnmew,0);
                   returnmingw = totwostring(returnmingw.substr(0,32)) + totwostring(returnmingw.substr(32,32));
                   if (out2.is_open()) {
                        out2<<returnmingw;
                   }
                }
            }
            out1.close();
            out2.close();
    
            return 0;
    }
    
    //还没做页面 其他感觉差不多了
    string IVstr= "0000000000000000000000000000000000000000000000000000000000000000" ;
    string xorxor(string w){ //都是64位数据
        //cout<<"ivstr.length"<<IVstr.length()<<endl;
        string resultxor = "";
         for(int i=0;i<w.size();i++){
    
            resultxor += to_string((w[i]^IVstr[i]));
        }
        //cout<<"resultxor.length"<<resultxor.length()<<endl;
        return resultxor;
    }
    //===================================================
    void producekey(bitset<64> bitkey){
    //过程:64位密钥经置换选择1去除奇偶校验位变成56位 分开左右各28位
    //循环移位:第一轮L1左移一位+R1(共56位)经过压缩置换2成48位:key1
    //L1(28)继续左移一位:L2+R1(28):R2(共56位)经过压缩置换成48位:key2
    //L2(28)继续左移2位:L2+R1(28):R2(共56位)经过压缩置换成48位...
    //共移位16轮 每轮移位位数不同 所以直接拿数组存 到时候直接取
          bitset<56>trans1;
          bitset<28>left1,left2;
          bitset<28>right1,right2;
          bitset<56>trans2;
          bitset<48>trans3;
          for(int i=0;i<56;++i){//缩成56位:去除了奇偶校验位
            trans1[55-i] = bitkey[64-PC_1[i]];
          }
         // cout<<"producekey()--trans1: "<<trans1<<endl;
          //分左右
          for(int i=0;i<28;++i){
            right1[i] = trans1[i];
            left1[i] = trans1[i+28];
          }
          //cout<<"producekey()--right1: "<<right1<<endl;
          //cout<<"producekey()--left1: "<<left1<<endl;
          for(int round=0;round<16;round++){//一轮生成1个密钥(48)
                  if(shiftBits[round] == 1){
                    for(int i=27; i>0; i--){
                        //循环向左移位
                        left2[i]=left1[i-shiftBits[round]];
                        right2[i]=right1[i-shiftBits[round]];
                    }
                    left2[0] = left1[27];
                    right2[0] = right1[27];
                  }else{
                      for(int i=27; i>1; i--){
                        //循环向左移位
                        left2[i]=left1[i-shiftBits[round]];
                        right2[i]=right1[i-shiftBits[round]];
                     }
                      left2[1] = left1[27];left2[0] = left1[26];
                      right2[1] = right1[27];right2[0] = right1[26];
                  }
                  //cout<<"round: "<<round<<" left2: "<<left2<<endl;
                 // cout<<"round: "<<round<<" right2: "<<right2<<endl;
    
                  for(int i=0;i<28;i++){ //数组合并 这肯定不行啊trans2 = left2+right2;//28!!
                    trans2[i] = right2[i] ;
                    trans2[i+28] = left2[i];
                  }
                  //压缩置换成48位
                  for(int i=0;i<48;++i){
                    trans3[47-i] = trans2[56-PC_2[i]];
                  }
                  keyarray[round] = trans3;
                  //cout<<"producekey()--round: "<<round<<"  "<<keyarray[round]<<endl;
                  left1 = left2;
                  right1 = right2;
          }
    
    }
    int changetoten(string s){//二进制的字符串转成10进制的数字
    
        int a,m,b=0,k=0;
        //a = atoi(s);//string转int C++中若需要将string类型转为int类型,需先将string转为const char*。
        char c[100];strcpy(c,s.c_str());
        a = atoi(c);
        while(a!=0){
            m = a%10;
            a/=10;
            b+=m*pow(2,k++);
        }
        return b;
    }
    string changetotwo(int a){//10进制数字转成二进制字符串
           string s;
           int result = 0, temp = a, j = 1;
    	   while(temp){
    		  result = result + j * (temp % 2);
    		  temp = temp / 2;
    		  j = j * 10;
    	   }
           char t[256];
           sprintf(t, "%04d", result);//字符串位数不足高位补0
           s = t;
           return s;//都要经过中间商char数组
    }
    string encrypt(bitset<64>bitkey,string strwen){ //参数得是64位bitset明文 返回64位密文
           // cout<<"first--xor: "<<strwen<<endl;
            bitset<64> bitencrypt(strwen);
            bitset<64> bitdecrypt;
            bitset<64> trans1;
            bitset<32> left1;
            bitset<32> right1;
            bitset<32> temp;
            bitset<48> trans2;
            bitset<32> transsbox;
            bitset<32> transpbox;
            bitset<48> transleft;
            for(int i=0;i<64;++i){
                trans1[63-i] = bitencrypt[64-IP[i]];
            }
            for(int i=0;i<32;++i){
                right1[i] =trans1[i];
                left1[i] = trans1[i+32];
            }
            //NO2:密钥整体的生成
            producekey(bitkey);
            //回来了
            for(int round=0;round<16;round++){
                 for(int i=0;i<48;++i){
                      transleft[47-i] = right1[32-E[i]];
                 }
                 transleft = transleft^keyarray[round];
                 string strtransleft = transleft.to_string();
                 string middles1,middles2;
                 int row,column,resu;
                 for(int i=0;i<48;i+=6){
                       middles1 = strtransleft.substr(i,6);
                       string bemiddles1,mimiddles1;
                       bemiddles1+=middles1[0];
                       bemiddles1+=middles1[5];
                       row = changetoten(bemiddles1);
                       mimiddles1+=middles1[1];
                       mimiddles1+=middles1[2];
                       mimiddles1+=middles1[3];
                       mimiddles1+=middles1[4];
                       column = changetoten(mimiddles1);
                       resu = S_BOX[i/6][row][column];
                       middles2.append(changetotwo(resu));
                 }
                 bitset<32> strtobit(middles2);
                 transsbox = strtobit;
                 for(int i=0;i<32;++i){
                     transpbox[31-i] = transsbox[32-P[i]];
                 }
                 temp = right1;
                 right1=left1^transpbox;
                 left1 = temp;
            }
            for(int i=0;i<32;++i){
                trans2[i] = left1[i];
                trans2[i+32] = right1[i];
            }
            for(int i=0;i<64;++i){
                 bitdecrypt[63-i] = trans2[64-IP_1[i]];
            }
            cout<<"encrypt()---密文: "<<bitdecrypt<<endl;
            return bitdecrypt.to_string();//转成64位二进制字符串
    
    }
    
    string decrypt(bitset<64>bitkey,string strwen){
            bitset<64> bitencrypt;
            bitset<64> bitdecrypt(strwen);
            bitset<64> trans1;
            bitset<32> left1;
            bitset<32> right1;
            bitset<32> temp;
            bitset<48> trans2;
            bitset<32> transsbox;
            bitset<32> transpbox;
            bitset<48> transleft;
            for(int i=0;i<64;++i){
                trans1[63-i] = bitdecrypt[64-IP[i]];
            }
            for(int i=0;i<32;++i){
                right1[i] =trans1[i];
                left1[i] = trans1[i+32];
            }
            //NO2:密钥整体的生成
            producekey(bitkey);
    
            for(int round=0;round<16;round++){
                 for(int i=0;i<48;++i){
                      transleft[47-i] = right1[32-E[i]];
                 }
                 transleft = transleft^keyarray[15-round];
                 string strtransleft = transleft.to_string();
                 string middles1,middles2;
                 int row,column,resu;
                 for(int i=0;i<48;i+=6){
                       middles1 = strtransleft.substr(i,6);
                       string bemiddles1,mimiddles1;
                       bemiddles1+=middles1[0];
                       bemiddles1+=middles1[5];
                       row = changetoten(bemiddles1);
                       mimiddles1+=middles1[1];
                       mimiddles1+=middles1[2];
                       mimiddles1+=middles1[3];
                       mimiddles1+=middles1[4];
                       column = changetoten(mimiddles1);
                       resu = S_BOX[i/6][row][column];
                       middles2.append(changetotwo(resu));
                 }
                 bitset<32> strtobit(middles2);
                 transsbox = strtobit;
                 for(int i=0;i<32;++i){
                     transpbox[31-i] = transsbox[32-P[i]];
                 }
                 temp = right1;
                 right1=left1^transpbox;
                 left1 = temp;
            }
            for(int i=0;i<32;++i){
                trans2[i] = left1[i];
                trans2[i+32] = right1[i];
            }
            for(int i=0;i<64;++i){
                 bitencrypt[63-i] = trans2[64-IP_1[i]];
            }
            cout<<"decrypt()--明文: "<<bitencrypt<<endl;
            return bitencrypt.to_string();//转成64位二进制字符串
    }
    
    string stringtotwo(string str){//字符转二进制 一个字符转8位二进制  这里改  改成字符串的
          unsigned char k=0x80;//https://blog.csdn.net/caiyaodeng/article/details/48998469
          string transsstr;
          //string转char*
          const char *schar = str.c_str();
          for(int i=0;i<strlen(schar);++i){
            unsigned char k=0x80;
            for(int j=0; j<8; j++, k >>= 1){
                if (schar[i]&k){
                    transsstr.append("1");
                }else{
                    transsstr.append("0");
                }
            }
         }
         return transsstr;
    }
    
    string convert(char p[]){ //16进制转成文本
        int i=0;
        while(p[2*i]!=''&&p[2*i+1]!='')//'' :ASCII码为0,表示一个字符串结束的标志
        {
            char c = p[2*i];
            if(c<='9')
              p[i] = (c-'0')<<4;
            else if(c<='F')
              p[i] = (c-'A'+10)<<4;
            else
              p[i] = (c-'a'+10)<<4;
            c = p[2*i+1];
            if(c<='9')
              p[i] += (c-'0');
            else if(c<='F')
              p[i] += (c-'A'+10);
            else
              p[i] += (c-'a'+10);
            i++;
        }
        p[i] = '';
        return p;
    }
    string totwostring(string str){ //32位二进制转成string
        string binary = str;
        string hex;
        stringstream ss;
        ss << std::hex << stoi(binary, nullptr, 2);//https://www.cnblogs.com/tsruixi/p/12944470.html
        ss >> hex;
        transform(hex.begin(), hex.end(), hex.begin(), ::toupper);//将某操作应用于指定范围的每个元素
        char a[100];
        strcpy(a,hex.c_str());
        return convert(a);
    }
    string process1(string mingw,int quesizezz){//该函数对这段64位明文 返回二进制的string密文
    
        string mystr3[3] = {"11223344","22334455","33445566"};
        string mytwo[3] = {"","",""};
        for(int z=0;z<3;z++){
            mytwo[z] = stringtotwo(mystr3[z]);
        }
        bitset<64>bitkey11(mytwo[0]);//用string初始化
        bitset<64>bitkey22(mytwo[1]);
        bitset<64>bitkey33(mytwo[2]);//k1 k2 k3
        mingw = xorxor(mingw);
        bitset<64>one(encrypt(bitkey33,decrypt(bitkey22,encrypt(bitkey11,mingw))));//加密过程 得到64位密文
        return one.to_string();
    }
    string process2(string mew,int quesizezz){//该函数对这段64位密文 返回二进制的string明文
    
        string mystr3[3] = {"11223344","22334455","33445566"};
        string mytwo[3] = {"","",""};
        for(int z=0;z<3;z++){
            mytwo[z] = stringtotwo(mystr3[z]);
        }
        bitset<64>bitkey11(mytwo[0]);
        bitset<64>bitkey22(mytwo[1]);
        bitset<64>bitkey33(mytwo[2]);
        mew = xorxor(mew);
        bitset<64>one(decrypt(bitkey11,encrypt(bitkey22,decrypt(bitkey33,mew))));//解密过程 得到64位明文
        return one.to_string();
    }
    int main(){
            TLE;//加快执行速度
            ofstream out1("ciphertext.txt");
            ofstream out2("later.txt");//写
    
            string returnmew;
            string returnmingw;
    
            //读明文文件 并补足 并分组
            ifstream in;
            in.open("former.txt");
            if(!in.is_open()){
                cerr<<"could not open this file"<<endl;
                exit(0);
            }
            char ch;
            string mingw;
            while(in.get(ch)){
                mingw.push_back(ch);
            }
            in.close();
            //cout<<"mingw1: "<<mingw<<endl;
            mingw = stringtotwo(mingw);
            //cout<<"mingw2: "<<mingw<<" mingw2.size(): "<<mingw.size()<<endl;
            int quesize = 64-(mingw.size()%64);
            //cout<<"quesize: "<<quesize<<endl;
            int i=0;
            if(quesize==64){//证明不缺
                 quesize = 0;
            }else{
                while(i < quesize){
                    mingw += '0';
                    i++;
                }
            }
            cout<<"mingw: "<<mingw<<endl;
            //mingw:有足够64倍数位的二进制string
    
            for(i=0;i<mingw.size();i=i+64){
                string s64 = mingw.substr(i,64);
                if((i == (mingw.size()-64)) && (quesize!=0)){//判断得出这是有缺失的最后一组64位
                   //cout<<"最后一组且有缺失"<<endl;
                   //cout<<"quesize: "<<quesize<<endl;
                   returnmew = process1(s64,quesize);//证明后面补0了
                    if (out1.is_open()) {
                        out1<<returnmew;
                    }
                   returnmingw = process2(returnmew,quesize);
                   returnmingw = totwostring(returnmingw.substr(0,32)) + totwostring(returnmingw.substr(32,32));
                   if (out2.is_open()) {
                        out2<<returnmingw;
                   }
                }else{
                    //cout<<"正常的64位"<<endl;
                    returnmew = process1(s64,0);
                    if (out1.is_open()) {
                        out1<<returnmew;
                    }
                   returnmingw = process2(returnmew,0);
                   returnmingw = totwostring(returnmingw.substr(0,32)) + totwostring(returnmingw.substr(32,32));
                   if (out2.is_open()) {
                        out2<<returnmingw;
                   }
                }
            }
            out1.close();
            out2.close();
    
            return 0;
    }
    
    
    #include<bits/stdc++.h>
    #define TLE ios::sync_with_stdio(0),cin.tie(0)
    using namespace std;
    
    bitset<48> keyarray[16];
    // 初始置换表
    int 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 };
    
    /*------------------下面是生成密钥所用表-----------------*/
    int PC_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};
    int PC_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};
    int shiftBits[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
    
    /*------------------轮函数-----------------*/
    // 扩展置换表,将32位扩展至48位
    int 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};
    // S盒,每个S盒是4x16的置换表,6位 -> 4位
    int S_BOX[8][4][16] = {
    	{
    		{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}
    	}
    };
    // P盒置换
    int 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 };
    /*--------------------------------------*/
    //初始逆置换
    int IP_1[] = {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};
    
    string IVstr= "0000000000000000000000000000000000000000000000000000000000000000" ;
    string xorxor(string w){ //都是64位数据
        //cout<<"ivstr.length"<<IVstr.length()<<endl;
        string resultxor = "";
         for(int i=0;i<w.size();i++){
    
            resultxor += to_string((w[i]^IVstr[i]));
        }
        //cout<<"resultxor.length"<<resultxor.length()<<endl;
        return resultxor;
    }
    //===================================================
    void producekey(bitset<64> bitkey){
    //过程:64位密钥经置换选择1去除奇偶校验位变成56位 分开左右各28位
    //循环移位:第一轮L1左移一位+R1(共56位)经过压缩置换2成48位:key1
    //L1(28)继续左移一位:L2+R1(28):R2(共56位)经过压缩置换成48位:key2
    //L2(28)继续左移2位:L2+R1(28):R2(共56位)经过压缩置换成48位...
    //共移位16轮 每轮移位位数不同 所以直接拿数组存 到时候直接取
          bitset<56>trans1;
          bitset<28>left1,left2;
          bitset<28>right1,right2;
          bitset<56>trans2;
          bitset<48>trans3;
          for(int i=0;i<56;++i){//缩成56位:去除了奇偶校验位
            trans1[55-i] = bitkey[64-PC_1[i]];
          }
         // cout<<"producekey()--trans1: "<<trans1<<endl;
          //分左右
          for(int i=0;i<28;++i){
            right1[i] = trans1[i];
            left1[i] = trans1[i+28];
          }
          //cout<<"producekey()--right1: "<<right1<<endl;
          //cout<<"producekey()--left1: "<<left1<<endl;
          for(int round=0;round<16;round++){//一轮生成1个密钥(48)
                  if(shiftBits[round] == 1){
                    for(int i=27; i>0; i--){
                        //循环向左移位
                        left2[i]=left1[i-shiftBits[round]];
                        right2[i]=right1[i-shiftBits[round]];
                    }
                    left2[0] = left1[27];
                    right2[0] = right1[27];
                  }else{
                      for(int i=27; i>1; i--){
                        //循环向左移位
                        left2[i]=left1[i-shiftBits[round]];
                        right2[i]=right1[i-shiftBits[round]];
                     }
                      left2[1] = left1[27];left2[0] = left1[26];
                      right2[1] = right1[27];right2[0] = right1[26];
                  }
                  //cout<<"round: "<<round<<" left2: "<<left2<<endl;
                 // cout<<"round: "<<round<<" right2: "<<right2<<endl;
    
                  for(int i=0;i<28;i++){ //数组合并 这肯定不行啊trans2 = left2+right2;//28!!
                    trans2[i] = right2[i] ;
                    trans2[i+28] = left2[i];
                  }
                  //压缩置换成48位
                  for(int i=0;i<48;++i){
                    trans3[47-i] = trans2[56-PC_2[i]];
                  }
                  keyarray[round] = trans3;
                  //cout<<"producekey()--round: "<<round<<"  "<<keyarray[round]<<endl;
                  left1 = left2;
                  right1 = right2;
          }
    
    }
    int changetoten(string s){//二进制的字符串转成10进制的数字
    
        int a,m,b=0,k=0;
        //a = atoi(s);//string转int C++中若需要将string类型转为int类型,需先将string转为const char*。
        char c[100];strcpy(c,s.c_str());
        a = atoi(c);
        while(a!=0){
            m = a%10;
            a/=10;
            b+=m*pow(2,k++);
        }
        return b;
    }
    string changetotwo(int a){//10进制数字转成二进制字符串
           string s;
           int result = 0, temp = a, j = 1;
    	   while(temp){
    		  result = result + j * (temp % 2);
    		  temp = temp / 2;
    		  j = j * 10;
    	   }
           char t[256];
           sprintf(t, "%04d", result);//字符串位数不足高位补0
           s = t;
           return s;//都要经过中间商char数组
    }
    string encrypt(bitset<64>bitkey,string strwen){ //参数得是64位bitset明文 返回64位密文
           // cout<<"first--xor: "<<strwen<<endl;
            bitset<64> bitencrypt(strwen);
            bitset<64> bitdecrypt;
            bitset<64> trans1;
            bitset<32> left1;
            bitset<32> right1;
            bitset<32> temp;
            bitset<48> trans2;
            bitset<32> transsbox;
            bitset<32> transpbox;
            bitset<48> transleft;
            for(int i=0;i<64;++i){
                trans1[63-i] = bitencrypt[64-IP[i]];
            }
            for(int i=0;i<32;++i){
                right1[i] =trans1[i];
                left1[i] = trans1[i+32];
            }
            //NO2:密钥整体的生成
            producekey(bitkey);
            //回来了
            for(int round=0;round<16;round++){
                 for(int i=0;i<48;++i){
                      transleft[47-i] = right1[32-E[i]];
                 }
                 transleft = transleft^keyarray[round];
                 string strtransleft = transleft.to_string();
                 string middles1,middles2;
                 int row,column,resu;
                 for(int i=0;i<48;i+=6){
                       middles1 = strtransleft.substr(i,6);
                       string bemiddles1,mimiddles1;
                       bemiddles1+=middles1[0];
                       bemiddles1+=middles1[5];
                       row = changetoten(bemiddles1);
                       mimiddles1+=middles1[1];
                       mimiddles1+=middles1[2];
                       mimiddles1+=middles1[3];
                       mimiddles1+=middles1[4];
                       column = changetoten(mimiddles1);
                       resu = S_BOX[i/6][row][column];
                       middles2.append(changetotwo(resu));
                 }
                 bitset<32> strtobit(middles2);
                 transsbox = strtobit;
                 for(int i=0;i<32;++i){
                     transpbox[31-i] = transsbox[32-P[i]];
                 }
                 temp = right1;
                 right1=left1^transpbox;
                 left1 = temp;
            }
            for(int i=0;i<32;++i){
                trans2[i] = left1[i];
                trans2[i+32] = right1[i];
            }
            for(int i=0;i<64;++i){
                 bitdecrypt[63-i] = trans2[64-IP_1[i]];
            }
            //cout<<"encrypt()---密文: "<<bitdecrypt<<endl;
            return bitdecrypt.to_string();//转成64位二进制字符串
    
    }
    
    string decrypt(bitset<64>bitkey,string strwen){
            bitset<64> bitencrypt;bitset<64> bitdecrypt(strwen);bitset<64> trans1;
            bitset<32> left1;bitset<32> right1;bitset<32> temp;
            bitset<48> trans2;bitset<32> transsbox;bitset<32> transpbox;
            bitset<48> transleft;
            for(int i=0;i<64;++i){
                trans1[63-i] = bitdecrypt[64-IP[i]];
            }
            for(int i=0;i<32;++i){
                right1[i] =trans1[i];
                left1[i] = trans1[i+32];
            }
            producekey(bitkey);
            for(int round=0;round<16;round++){
                 for(int i=0;i<48;++i){
                      transleft[47-i] = right1[32-E[i]];
                 }
                 transleft = transleft^keyarray[15-round];//区别之一
                 string strtransleft = transleft.to_string();
                 string middles1,middles2;
                 int row,column,resu;
                 for(int i=0;i<48;i+=6){
                       middles1 = strtransleft.substr(i,6);
                       string bemiddles1,mimiddles1;
                       bemiddles1+=middles1[0];
                       bemiddles1+=middles1[5];
                       row = changetoten(bemiddles1);
                       mimiddles1+=middles1[1];
                       mimiddles1+=middles1[2];
                       mimiddles1+=middles1[3];
                       mimiddles1+=middles1[4];
                       column = changetoten(mimiddles1);
                       resu = S_BOX[i/6][row][column];
                       middles2.append(changetotwo(resu));
                 }
                 bitset<32> strtobit(middles2);
                 transsbox = strtobit;
                 for(int i=0;i<32;++i){
                     transpbox[31-i] = transsbox[32-P[i]];
                 }
                 temp = right1;
                 right1=left1^transpbox;
                 left1 = temp;
            }
            for(int i=0;i<32;++i){
                trans2[i] = left1[i];
                trans2[i+32] = right1[i];
            }
            for(int i=0;i<64;++i){
                 bitencrypt[63-i] = trans2[64-IP_1[i]];
            }
            return bitencrypt.to_string();//转成64位二进制字符串
    }
    
    string stringtotwo(string str){//字符转二进制 一个字符转8位二进制  这里改  改成字符串的
          unsigned char k=0x80;//https://blog.csdn.net/caiyaodeng/article/details/48998469
          string transsstr;
          //string转char*
          const char *schar = str.c_str();
          for(int i=0;i<strlen(schar);++i){
            unsigned char k=0x80;
            for(int j=0; j<8; j++, k >>= 1){
                if (schar[i]&k){
                    transsstr.append("1");
                }else{
                    transsstr.append("0");
                }
            }
         }
         return transsstr;
    }
    
    string convert(char p[]){ //16进制转成文本
        int i=0;
        while(p[2*i]!=''&&p[2*i+1]!='')//'' :ASCII码为0,表示一个字符串结束的标志
        {
            char c = p[2*i];
            if(c<='9')
              p[i] = (c-'0')<<4;
            else if(c<='F')
              p[i] = (c-'A'+10)<<4;
            else
              p[i] = (c-'a'+10)<<4;
            c = p[2*i+1];
            if(c<='9')
              p[i] += (c-'0');
            else if(c<='F')
              p[i] += (c-'A'+10);
            else
              p[i] += (c-'a'+10);
            i++;
        }
        p[i] = '';
        return p;
    }
    string totwostring(string str){ //32位二进制转成string
        string binary = str;
        string hex;
        stringstream ss;
        ss << std::hex << stoi(binary, nullptr, 2);//https://www.cnblogs.com/tsruixi/p/12944470.html
        ss >> hex;
        transform(hex.begin(), hex.end(), hex.begin(), ::toupper);//将某操作应用于指定范围的每个元素
        char a[100];
        strcpy(a,hex.c_str());
        return convert(a);
    }
    string process1(string mingw,int quesizezz){//该函数对这段64位明文 返回二进制的string密文
    
        string mystr3[3] = {"11223344","22334455","33445566"};
        string mytwo[3] = {"","",""};
        for(int z=0;z<3;z++){
            mytwo[z] = stringtotwo(mystr3[z]);
        }
        bitset<64>bitkey11(mytwo[0]);//用string初始化
        bitset<64>bitkey22(mytwo[1]);
        bitset<64>bitkey33(mytwo[2]);//k1 k2 k3
        mingw = xorxor(mingw);
        bitset<64>one(encrypt(bitkey33,decrypt(bitkey22,encrypt(bitkey11,mingw))));//加密过程 得到64位密文
        return one.to_string();
    }
    string process2(string mew,int quesizezz){//该函数对这段64位密文 返回二进制的string明文
    
        string mystr3[3] = {"11223344","22334455","33445566"};
        string mytwo[3] = {"","",""};
        for(int z=0;z<3;z++){
            mytwo[z] = stringtotwo(mystr3[z]);
        }
        bitset<64>bitkey11(mytwo[0]);
        bitset<64>bitkey22(mytwo[1]);
        bitset<64>bitkey33(mytwo[2]);
        mew = xorxor(mew);
        bitset<64>one(decrypt(bitkey11,encrypt(bitkey22,decrypt(bitkey33,mew))));//解密过程 得到64位明文
        return one.to_string();
    }
    void start(){ //一句话没写完 换行了 换行符应该处理
        ofstream out1("ciphertext.txt");
        ofstream out2("later.txt");//写
    
        string returnmew;
        string returnmingw;
        //读明文文件 并补足 并分组
        ifstream in;
        in.open("former.txt");
        if(!in.is_open()){
            cerr<<"could not open this file"<<endl;
            exit(0);
        }//对文件内容开始处理
        string str;
        while(getline(in,str)){ //按行处理
             cout<<str<<endl;
             char ch;
             string mingw = str;
    //        while(in.get(ch)){
    //            mingw.push_back(ch);
    //        }
    //        in.close();
            //cout<<"mingw1: "<<mingw<<endl;
            mingw = stringtotwo(mingw);
            //cout<<"mingw2: "<<mingw<<" mingw2.size(): "<<mingw.size()<<endl;
            int quesize = 64-(mingw.size()%64);
            //cout<<"quesize: "<<quesize<<endl;
            int i=0;
            if(quesize==64){//证明不缺
                 quesize = 0;
            }else{
                while(i < quesize){
                    mingw += '0';
                    i++;
                }
            }
            //cout<<"mingw: "<<mingw<<endl;
            for(i=0;i<mingw.size();i=i+64){//mingw:有足够64倍数位的二进制string
                string s64 = mingw.substr(i,64);
                if((i == (mingw.size()-64)) && (quesize!=0)){//判断得出这是有缺失的最后一组64位
                   //cout<<"最后一组且有缺失"<<endl;
                   //cout<<"quesize: "<<quesize<<endl;
                   returnmew = process1(s64,quesize);//证明后面补0了
                    if (out1.is_open()) {
                        out1<<returnmew;
                    }
                   returnmingw = process2(returnmew,quesize);
                   returnmingw = totwostring(returnmingw.substr(0,32)) + totwostring(returnmingw.substr(32,32));
                   if (out2.is_open()) {
                        out2<<returnmingw;
                   }
                }else{
                    //cout<<"正常的64位"<<endl;
                    returnmew = process1(s64,0);
                    if (out1.is_open()) {
                        out1<<returnmew;
                    }
                   returnmingw = process2(returnmew,0);
                   returnmingw = totwostring(returnmingw.substr(0,32)) + totwostring(returnmingw.substr(32,32));
                   if (out2.is_open()) {
                        out2<<returnmingw;
                   }
                }
            }
           out2<<endl;//输出到文件时也换行操作
        }
    
    //    char ch;
    //    string mingw;
    //    while(in.get(ch)){
    //        mingw.push_back(ch);
    //    }
    //    in.close();
    //    //cout<<"mingw1: "<<mingw<<endl;
    //    mingw = stringtotwo(mingw);
    //    //cout<<"mingw2: "<<mingw<<" mingw2.size(): "<<mingw.size()<<endl;
    //    int quesize = 64-(mingw.size()%64);
    //    //cout<<"quesize: "<<quesize<<endl;
    //    int i=0;
    //    if(quesize==64){//证明不缺
    //         quesize = 0;
    //    }else{
    //        while(i < quesize){
    //            mingw += '0';
    //            i++;
    //        }
    //    }
    //    //cout<<"mingw: "<<mingw<<endl;
    //    for(i=0;i<mingw.size();i=i+64){//mingw:有足够64倍数位的二进制string
    //        string s64 = mingw.substr(i,64);
    //        if((i == (mingw.size()-64)) && (quesize!=0)){//判断得出这是有缺失的最后一组64位
    //           //cout<<"最后一组且有缺失"<<endl;
    //           //cout<<"quesize: "<<quesize<<endl;
    //           returnmew = process1(s64,quesize);//证明后面补0了
    //            if (out1.is_open()) {
    //                out1<<returnmew;
    //            }
    //           returnmingw = process2(returnmew,quesize);
    //           returnmingw = totwostring(returnmingw.substr(0,32)) + totwostring(returnmingw.substr(32,32));
    //           if (out2.is_open()) {
    //                out2<<returnmingw;
    //           }
    //        }else{
    //            //cout<<"正常的64位"<<endl;
    //            returnmew = process1(s64,0);
    //            if (out1.is_open()) {
    //                out1<<returnmew;
    //            }
    //           returnmingw = process2(returnmew,0);
    //           returnmingw = totwostring(returnmingw.substr(0,32)) + totwostring(returnmingw.substr(32,32));
    //           if (out2.is_open()) {
    //                out2<<returnmingw;
    //           }
    //        }
    //    }
    
        //文件内容处理完毕
        out1.close();
        out2.close();
    
    }
    int main(){
            TLE;//加快执行速度
            start();
    
            return 0;
    }
    
    

    代码移植到QT上

    #ifndef WIDGET_H
    #define WIDGET_H
    #include<bits/stdc++.h>//https://blog.csdn.net/Niro_z/article/details/8028996
    #include <QWidget>
    #include <QPushButton>
    using namespace std;
    
    
    namespace Ui {
    class Widget;
    }
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit Widget(QWidget *parent = 0);
        ~Widget();
    
        string xorxor(string w);
        void producekey(bitset<64> bitkey);
        int changetoten(string s);
        string changetotwo(int a);
        string encrypt(bitset<64>bitkey,string strwen);
        string decrypt(bitset<64>bitkey,string strwen);
        string stringtotwo(string str);
        string convert(char p[]);
        string totwostring(string str);
        string process1(string mingw,int quesizezz);
        string process2(string mew,int quesizezz);
        void start();
    
    private:
        Ui::Widget *ui;
        QPushButton button;
    };
    
    #endif // WIDGET_H
    
    

    '''

    include "widget.h"

    include "ui_widget.h"

    include

    include<bits/stdc++.h>

    include

    include

    include //可以指定编码

    include

    include

    define TLE ios::sync_with_stdio(0),cin.tie(0)

    using namespace std;

    bitset<48> keyarray[16];
    int 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 };

    int PC_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};
    int PC_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};
    int shiftBits[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};

    int 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};
    int S_BOX[8][4][16] = {
    {
    {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}
    }
    };
    int 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 };
    int IP_1[] = {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};
    string IVstr= "0000000000000000000000000000000000000000000000000000000000000000" ;

    Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
    {
    ui->setupUi(this);

    //构造函数
    button.setParent(this);
    button.setText("3DES加密");
    button.move(100,100);
    //connect(&button,&QPushButton::clicked,this,&Widget::close);
    connect(&button,&QPushButton::clicked,this,&Widget::start);
    

    }

    Widget::~Widget()
    {
    delete ui;
    }

    string Widget::xorxor(string w){
    string resultxor = "";
    for(int i=0;i<w.size();i++){

        resultxor += to_string((w[i]^IVstr[i]));
    }
    return resultxor;
    

    }

    void Widget::producekey(bitset<64> bitkey){
    bitset<56>trans1;
    bitset<28>left1,left2;
    bitset<28>right1,right2;
    bitset<56>trans2;
    bitset<48>trans3;
    for(int i=0;i<56;++i){
    trans1[55-i] = bitkey[64-PC_1[i]];
    }

      for(int i=0;i<28;++i){
        right1[i] = trans1[i];
        left1[i] = trans1[i+28];
      }
      for(int round=0;round<16;round++){
              if(shiftBits[round] == 1){
                for(int i=27; i>0; i--){
                    left2[i]=left1[i-shiftBits[round]];
                    right2[i]=right1[i-shiftBits[round]];
                }
                left2[0] = left1[27];
                right2[0] = right1[27];
              }else{
                  for(int i=27; i>1; i--){
                    left2[i]=left1[i-shiftBits[round]];
                    right2[i]=right1[i-shiftBits[round]];
                 }
                  left2[1] = left1[27];left2[0] = left1[26];
                  right2[1] = right1[27];right2[0] = right1[26];
              }
              for(int i=0;i<28;i++){
                trans2[i] = right2[i] ;
                trans2[i+28] = left2[i];
              }
              for(int i=0;i<48;++i){
                trans3[47-i] = trans2[56-PC_2[i]];
              }
              keyarray[round] = trans3;
              left1 = left2;
              right1 = right2;
      }
    

    }

    int Widget::changetoten(string s){
    int a,m,b=0,k=0;
    char c[100];strcpy(c,s.c_str());
    a = atoi(c);
    while(a!=0){
    m = a%10;
    a/=10;
    b+=m*pow(2,k++);
    }
    return b;
    }

    string Widget::changetotwo(int a){
    string s;
    int result = 0, temp = a, j = 1;
    while(temp){
    result = result + j * (temp % 2);
    temp = temp / 2;
    j = j * 10;
    }
    char t[256];
    sprintf(t, "%04d", result);
    s = t;
    return s;
    }

    string Widget::encrypt(bitset<64>bitkey,string strwen){
    bitset<64> bitencrypt(strwen);
    bitset<64> bitdecrypt;
    bitset<64> trans1;
    bitset<32> left1;
    bitset<32> right1;
    bitset<32> temp;
    bitset<48> trans2;
    bitset<32> transsbox;
    bitset<32> transpbox;
    bitset<48> transleft;
    for(int i=0;i<64;++i){
    trans1[63-i] = bitencrypt[64-IP[i]];
    }
    for(int i=0;i<32;++i){
    right1[i] =trans1[i];
    left1[i] = trans1[i+32];
    }
    producekey(bitkey);
    for(int round=0;round<16;round++){
    for(int i=0;i<48;++i){
    transleft[47-i] = right1[32-E[i]];
    }
    transleft = transleft^keyarray[round];
    string strtransleft = transleft.to_string();
    string middles1,middles2;
    int row,column,resu;
    for(int i=0;i<48;i+=6){
    middles1 = strtransleft.substr(i,6);
    string bemiddles1,mimiddles1;
    bemiddles1+=middles1[0];
    bemiddles1+=middles1[5];
    row = changetoten(bemiddles1);
    mimiddles1+=middles1[1];
    mimiddles1+=middles1[2];
    mimiddles1+=middles1[3];
    mimiddles1+=middles1[4];
    column = changetoten(mimiddles1);
    resu = S_BOX[i/6][row][column];
    middles2.append(changetotwo(resu));
    }
    bitset<32> strtobit(middles2);
    transsbox = strtobit;
    for(int i=0;i<32;++i){
    transpbox[31-i] = transsbox[32-P[i]];
    }
    temp = right1;
    right1=left1^transpbox;
    left1 = temp;
    }
    for(int i=0;i<32;++i){
    trans2[i] = left1[i];
    trans2[i+32] = right1[i];
    }
    for(int i=0;i<64;++i){
    bitdecrypt[63-i] = trans2[64-IP_1[i]];
    }
    return bitdecrypt.to_string();
    }

    string Widget::decrypt(bitset<64>bitkey,string strwen){
    bitset<64> bitencrypt;bitset<64> bitdecrypt(strwen);bitset<64> trans1;
    bitset<32> left1;bitset<32> right1;bitset<32> temp;
    bitset<48> trans2;bitset<32> transsbox;bitset<32> transpbox;
    bitset<48> transleft;
    for(int i=0;i<64;++i){
    trans1[63-i] = bitdecrypt[64-IP[i]];
    }
    for(int i=0;i<32;++i){
    right1[i] =trans1[i];
    left1[i] = trans1[i+32];
    }
    producekey(bitkey);
    for(int round=0;round<16;round++){
    for(int i=0;i<48;++i){
    transleft[47-i] = right1[32-E[i]];
    }
    transleft = transleft^keyarray[15-round];//区别之一
    string strtransleft = transleft.to_string();
    string middles1,middles2;
    int row,column,resu;
    for(int i=0;i<48;i+=6){
    middles1 = strtransleft.substr(i,6);
    string bemiddles1,mimiddles1;
    bemiddles1+=middles1[0];
    bemiddles1+=middles1[5];
    row = changetoten(bemiddles1);
    mimiddles1+=middles1[1];
    mimiddles1+=middles1[2];
    mimiddles1+=middles1[3];
    mimiddles1+=middles1[4];
    column = changetoten(mimiddles1);
    resu = S_BOX[i/6][row][column];
    middles2.append(changetotwo(resu));
    }
    bitset<32> strtobit(middles2);
    transsbox = strtobit;
    for(int i=0;i<32;++i){
    transpbox[31-i] = transsbox[32-P[i]];
    }
    temp = right1;
    right1=left1^transpbox;
    left1 = temp;
    }
    for(int i=0;i<32;++i){
    trans2[i] = left1[i];
    trans2[i+32] = right1[i];
    }
    for(int i=0;i<64;++i){
    bitencrypt[63-i] = trans2[64-IP_1[i]];
    }
    return bitencrypt.to_string();
    }

    string Widget::stringtotwo(string str){
    unsigned char k=0x80;
    string transsstr;
    const char *schar = str.c_str();
    for(int i=0;i<strlen(schar);++i){
    unsigned char k=0x80;
    for(int j=0; j<8; j++, k >>= 1){
    if (schar[i]&k){
    transsstr.append("1");
    }else{
    transsstr.append("0");
    }
    }
    }
    return transsstr;
    }

    string Widget::convert(char p[]){
    int i=0;
    while(p[2i]!=''&&p[2i+1]!='')
    {
    char c = p[2i];
    if(c<='9')
    p[i] = (c-'0')<<4;
    else if(c<='F')
    p[i] = (c-'A'+10)<<4;
    else
    p[i] = (c-'a'+10)<<4;
    c = p[2
    i+1];
    if(c<='9')
    p[i] += (c-'0');
    else if(c<='F')
    p[i] += (c-'A'+10);
    else
    p[i] += (c-'a'+10);
    i++;
    }
    p[i] = '';
    return p;
    }

    string Widget::totwostring(string str){
    string binary = str;
    string hex;
    stringstream ss;
    ss << std::hex << stoi(binary, nullptr, 2);
    ss >> hex;
    transform(hex.begin(), hex.end(), hex.begin(), ::toupper);
    char a[100];
    strcpy(a,hex.c_str());
    return convert(a);
    }

    string Widget::process1(string mingw,int quesizezz){

    string mystr3[3] = {"11223344","22334455","33445566"};
    string mytwo[3] = {"","",""};
    for(int z=0;z<3;z++){
        mytwo[z] = stringtotwo(mystr3[z]);
    }
    bitset<64>bitkey11(mytwo[0]);
    bitset<64>bitkey22(mytwo[1]);
    bitset<64>bitkey33(mytwo[2]);
    mingw = xorxor(mingw);
    bitset<64>one(encrypt(bitkey33,decrypt(bitkey22,encrypt(bitkey11,mingw))));
    return one.to_string();
    

    }
    string Widget::process2(string mew,int quesizezz){

    string mystr3[3] = {"11223344","22334455","33445566"};
    string mytwo[3] = {"","",""};
    for(int z=0;z<3;z++){
        mytwo[z] = stringtotwo(mystr3[z]);
    }
    bitset<64>bitkey11(mytwo[0]);
    bitset<64>bitkey22(mytwo[1]);
    bitset<64>bitkey33(mytwo[2]);
    mew = xorxor(mew);
    bitset<64>one(decrypt(bitkey11,encrypt(bitkey22,decrypt(bitkey33,mew))));
    return one.to_string();
    

    }

    void Widget::start(){
    TLE;
    QString str;
    string returnmew;string returnmingw;

    QFile out1("E:\QT\QTCode\1129\ciphertext.txt");
    QFile out2("E:\QT\QTCode\1129\later.txt");
    QTextStream txtOutput1(&out1);
    QTextStream txtOutput2(&out2);
    
    
    QFile aFile("E:\QT\QTCode\1129\former.txt");
    
    if (!aFile.exists()) {
        cout<<"error"<<endl;
    }
    
    if (!aFile.open(QIODevice::ReadOnly | QIODevice::Text)){
        cout<<"error"<<endl;
    }
    
    QTextStream aStream(&aFile); //用文本流读取文件
    while(!aStream.atEnd()){   //进不来getline(in,str)
        str = aStream.readLine();
        char ch;
        string mingw = string((const char *)str.toLocal8Bit());;
        mingw = stringtotwo(mingw);
        int quesize = 64-(mingw.size()%64);
        int i=0;
        if(quesize==64){
             quesize = 0;
        }else{
            while(i < quesize){
                mingw += '0';
                i++;
            }
        }
        for(i=0;i<mingw.size();i=i+64){
            string s64 = mingw.substr(i,64);
            if((i == (mingw.size()-64)) && (quesize!=0)){
               returnmew = process1(s64,quesize);
                if (out1.open(QIODevice::WriteOnly)) {
                    //out1<<returnmew;
                    txtOutput1 << QString(QString::fromLocal8Bit(returnmew.c_str()));
                }
               //txtOutput1<<returnmew;
               //txtOutput1 << QString(QString::fromLocal8Bit(returnmew.c_str()));
               returnmingw = process2(returnmew,quesize);
               returnmingw = totwostring(returnmingw.substr(0,32)) + totwostring(returnmingw.substr(32,32));
               if (out2.open(QIODevice::WriteOnly)) {
                    txtOutput2<< QString(QString::fromLocal8Bit(returnmingw.c_str()));
               }
               //txtOutput2<< QString(QString::fromLocal8Bit(returnmingw.c_str()));
            }else{
                returnmew = process1(s64,0);
                if (out1.open(QIODevice::WriteOnly)) {
                   // out1<<returnmew;
                    txtOutput1<<QString(QString::fromLocal8Bit(returnmingw.c_str()));
                }
                txtOutput1<<QString(QString::fromLocal8Bit(returnmingw.c_str()));
               returnmingw = process2(returnmew,0);
               returnmingw = totwostring(returnmingw.substr(0,32)) + totwostring(returnmingw.substr(32,32));
               if (out2.open(QIODevice::WriteOnly)) {
                   txtOutput2<<QString(QString::fromLocal8Bit(returnmingw.c_str()));
               }
               //txtOutput2<<QString(QString::fromLocal8Bit(returnmingw.c_str()));
            }
        }
       txtOutput2<<endl;
    }
    out1.close();
    out2.close();
    

    }

    '''

    #include "widget.h"
    #include <QApplication>
    #include <QPushButton>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;//去执行构造函数
        w.setWindowTitle(QString("3DES加解密"));
        w.resize(600,600);
        w.show();
        return a.exec();
    }
    
    
  • 相关阅读:
    [模板] 循环数组的最大子段和
    [最短路][几何][牛客] [国庆集训派对1]-L-New Game
    [洛谷] P1866 编号
    1115 Counting Nodes in a BST (30 分)
    1106 Lowest Price in Supply Chain (25 分)
    1094 The Largest Generation (25 分)
    1090 Highest Price in Supply Chain (25 分)
    树的遍历
    1086 Tree Traversals Again (25 分)
    1079 Total Sales of Supply Chain (25 分 树
  • 原文地址:https://www.cnblogs.com/yundong333/p/13953048.html
Copyright © 2011-2022 走看看