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();
    }
    
    
  • 相关阅读:
    支持向量机(二)
    kafka partiton迁移方法与原理
    park和unpark
    Replicated State Machine和WAL
    thrift源码分析
    thrift使用和源码分析
    kafka源码环境搭建
    kafka指定partiton生产
    gradle构建scala
    kafka consumer代码梳理
  • 原文地址:https://www.cnblogs.com/yundong333/p/13953048.html
Copyright © 2011-2022 走看看