DES加密算法课程设计报告

软件实现流程图

二、标准DES的加密过程

1、明文与密钥的输入

       首先8位ACSII字符的明文与密钥的输入,存放在mingwen[8]和miyao[8]中,然后将这些8位的ASCII字符转换成二进制的64位的明文和密钥,分别存放在mingwenB[64]和miyaoB[64]中,并将二进制的明文和密钥放在文件中

       int str[8],i,j,ch,k;

       FILE *fp4;fp4=fopen("明文二进制.txt","w");

       k=0;

       for(i=0;i<8;i++)

    {

       ch=mingwen[i];

       for(j=0;j<8;j++)

       {

           str[j]=ch%2;

           ch=ch/2;

       }

       for(j=7;j>=0;j--)

       {

           mingwenB[k]=str[j];

           k++;

           fprintf(fp4,"%d",str[j]);

       }

    }

   密钥的转换和存储同理。

2、密钥的产生

    1)、64位miyaoB[64]经过pc-1置换,生成56位的比特串。定义pc1_Table[56],存放在afterpc1[56]中。

       for(i=0;i<56;i++) afterpc1[i]=miyaoB[pc1_Table[i]-1];

    2)、56位比特串分组,生成C0[28]和D0[28]

       for(i=0;i<28;i++) C0[i]=afterpc1[i];

       for(j=0,i=28;i<56;i++,j++) D0[j]=afterpc1[i];

    3)、C0[28]、D0[28]进行左移,产生C[16][28]和D[16][28],为进行pc-2置换产生密钥做准备。

       for(i=0;i<27;i++)        //第一轮数据生成C[0][28]与D[0][28]

        {

           C[0][i]=C0[i+1];

           D[0][i]=D0[i+1];

        }

        C[0][27]=C0[0];

        D[0][27]=D0[0];

           for(i=1;i<16;i++)        //第二轮数据至第十六轮数据生成

    {   if(i==1||i==8||i==15)

       {   for(j=0;j<27;j++)            //左移1位

           {

              C[i][j]=C[i-1][j+1];

              D[i][j]=D[i-1][j+1];

           }

           C[i][27]=C[i-1][0];

           D[i][27]=D[i-1][0];

       }

       else                     //左移2位

       {

           for(j=0;j<26;j++)

           {

              C[i][j]=C[i-1][j+2];

              D[i][j]=D[i-1][j+2];

           }

           C[i][26]=C[i-1][0];

           C[i][27]=C[i-1][1];

           D[i][26]=D[i-1][0];

           D[i][27]=D[i-1][1];

       }

    }             //产生16轮左右数据,为pc-2置换准备。

    4)、左右两部分比特串合并,存放在int beforekey[16][56]中

           k=0;

           for(i=0;i<16;i++)

           {

              for(j=0;j<28;j++)

                  beforekey[i][j]=C[i][j];

              for(k=0;k<28;k++,j++)

                  beforekey[i][j]=D[i][k];

           }

    5)、beforekey[16][56]经过pc-2置换,产生16轮密钥keys[16][48],

           for(i=0;i<16;i++)

              for(j=0;j<48;j++)

                  keys[i][j]=beforekey[i][pc_2table[j]-1];

至此,16轮子密钥产生完毕,为keys[16][48]。

3、密文的产生

    1)、明文经过初始置换IP置换。结果放在afterIP[64]中。

           for(j=0;j<64;j++)

           {

              afterIP[j]=mingwenB[IP_table[j]-1];

           }

    2)、明文的第0次分组,左部分L0[32],右部分R0[32]。

           for(i=0;i<32;i++)

              L0[i]=afterIP[i];

           for(j=0,i=32;i<64;i++,j++)

              R0[j]=afterIP[i];

    3)、为产生密文,要进行16轮的循环,每次循环生成一个L[i][32]和R[i][32],下面进行第一次循环,生成L[0][32]和R[0][32]。

           for(i=0;i<32;i++)    //Li=R(i-1)

              L[0][i]=R0[i];

    4)、至于R[0][32]的生成,R[0][32]=L0[32]^f(R0,keys[0])。因此,要首先计算出f值。R0[32]经过E变换,由32位扩展为48位,然后与子密钥进行异或,为进入S盒做准备。结果放在afterER0[48]中

           for(i=0;i<48;i++)   

              afterER0[i]=R0[E_table[i]-1];

    5)、E扩展后,与子密钥进行异或,生成进入S盒前的数据。存放在beforeS[48].

           for(i=0;i<48;i++)

              if(afterER0[i]==keys[0][i])

                  beforeS[i]=0;

              else

                  beforeS[i]=1;

    6)、要进入S盒的48位比特串要经过8个不同的S盒,因此,将48位比特串分在8个数组中,放在beforeSBox[8][6].

            for(k=0,i=0;i<8;i++)

              for(j=0;j<6;j++)

              {   beforeSBox[i][j]=beforeS[k];

                  k++;

              }

    7)、进入S盒后,进过8个S盒,每个S盒产生一个十进制的数字,在0~15之间。beforeSBox[i][6]中的6个数字,第0、5位组成了S盒的行号,第1、2、3、4,4位组成了S盒的列号,根据行列选中S盒中的数据作为输出,存放在afterSBox[8]中。

           int hang,lie;

           for(i=0;i<8;i++)

           {   hang=beforeSBox[i][0]*2+beforeSBox[i][5];                lie=beforeSBox[i][1]*8+beforeSBox[i][2]*4+beforeSBox[i][3]*2+beforeSBox[i][4];

       afterSBox[i]=SBox[i][hang][lie];

    }

    8)、由S盒出来的8个十进制数字转换成32位的二进制比特串,存放在beroreP[32]中,为接下来的P置换做准备。

       k=0;   int temp;

        int str1[4];

        for(i=0;i<8;i++)

        {

           temp=afterSBox[i];

           for(j=0;j<4;j++)

           {  

               str1[j]=temp%2;

               temp=temp/2;

           }

           for(j=3;j>=0;j--)

           {

               beforep[k]=str1[j];

               k++;

           }

        }

    9)、转换为二进制的32位比特串进行P置换,生成新的32位比特串,也就是f的值。存放在P[32]中。

       for(i=0;i<32;i++)

           p[i]=beforep[p_table[i]-1];

    至此,第一轮的循环已经完成,成功产生了L[0][32]和R[0][32]。

    10)、对于剩下的15轮循环,用一个循环语句进行控制,生成余下的15轮中间数据的左部和右部,最后产生L[15][32]和R[15][32]。

    11)、得到的最后一轮左部32位比特串和右部32位比特串进行合并,但是,合并的时候,右部32位比特串在前,R[15][32]在前,而L[15][32]在后。结果存放在beforeoutput[64]中

       for(i=0;i<32;i++)    //数据合并,R[15][32]在前,L[15][32]在后面

           beforeoutput[i]=R[15][i];

        for(i=32,j=0;i<64;i++,j++)

           beforeoutput[i]=L[15][j];

    12)、左右数据合并后的比特串进行最后的逆置换,生成64位的二进制密文。存放在output[64]中。

       for(i=0;i<64;i++)

           output[i]=beforeoutput[IPR_tabel[i]-1];//得到64位密文

    13)、将得到的64位密文转换为8位的ASCII字符。

           int charB[8][8];  k=0; char miwen[8];

           for(i=0;i<8;i++)

              for(j=0;j<8;j++)

              {

                  charB[i][j]=output[k];

                  k++;

              }             

           for(i=0;i<8;i++)

           {

              str[i]=0;

              if(charB[i][0]==1)

               str[i]=str[i]+128;

           if(charB[i][1]==1)

               str[i]=str[i]+64;

           if(charB[i][2]==1)

               str[i]=str[i]+32;

           if(charB[i][3]==1)

               str[i]=str[i]+16;

           if(charB[i][4]==1)

               str[i]=str[i]+8;

           if(charB[i][5]==1)

               str[i]=str[i]+4;

           if(charB[i][6]==1)

               str[i]=str[i]+2;

           if(charB[i][7]==1)

               str[i]=str[i]+1;

        }  

        m_outputMiwen="";

        for(i=0;i<8;i++)

           miwen[i]=str[i];     //至此,得到密文miwen[8]

三、标准DES的解密过程

    解密与加密的过程几乎完全相同,唯一不同的地方是:在进行E扩展后要与子密钥进行异或的时候,第一轮要与第十六轮子密钥进行异或。依次类推,第十六轮要与第一轮子密钥进行异或。因此对于DES的解密过程就不再细说。

程序运行结果截图

1、初始界面,界面的初始化输入的明文/密文是“20082374”,也就是学号作为待加密数据。

2、点击加密:进入加密界面,在这个界面里显示加密过程中的所有细节,包括循环的次数,每轮循环的子密钥、左右部数据。

3、再次点击加密按钮,进行数据的加密,64位的明文经过加密生成64位密文,“64位明文:”是输入的8位明文的二进制表示。“64位密钥:”是输入的8位密钥的二进制表示。“64位密文:”是经过加密之后产生的密文。“循环轮数”是记录十六轮循环的次数。“子密钥”记录每次循环的时候与R(i-1)进行异或的48位子密钥。“左部(Li)”指的是每次循环生成的Li,左部32位比特串。“右部(Ri)”指的是每次循环产生的右部Ri,32位比特串。

4、点击返回按钮,返回主界面。

5、点击解密按钮,进入解密界面,在这个界面里显示了解密过程中的所有细节,包括循环的次数,每轮循环的子密钥、左右部数据。

6、点击解密按钮,进行数据的加密,64位的密文经过解密生成64位的明文,“64位密文:”是输入的8位密文的二进制表示。“64位密钥:”是输入的8位密钥的二进制表示。“64位明文:”是经过解密之后产生的明文。“循环轮数”是记录十六轮循环的次数。“子密钥”记录每次循环的时候与R(i-1)进行异或的48位子密钥。“左部(Li)”指的是每次循环生成的Li,左部32位比特串。“右部(Ri)”指的是每次循环产生的右部Ri,32位比特串。

7、点击返回按钮,返回主界面

8、点击退出按钮,退出程序,程序结束。


密文对密钥敏感性的测试

   在明文不变的情况下,通过对密钥改变一位和多位进行密文对密钥敏感性的测试,观察密文的改变情况。下面给出部分数据和分析结果。

    例:明文:20082374

密钥:1:abcdefgh ,2:bbcdefgh 3:abddefgh 4:accdefgh 5:abcdefgi 6:abcdefgg

7:abcdefhg 8:abcdeffh 9:abcdefhh 10:abcdeggh 11:abcdeegh

这下密钥均是相对于密钥“abcdefgh”改变一位,得到的密文如下:

01:11100011 00001001 11010000 10111000 00101101 01101011 00011101 00111101

02:01101001 01111100 10001101 00111010 00101110 01000011 11000101 00011110

03:00010110 01011100 10100010 00100111 01101111 11100000 11110000 11000001

04:11100011 00001001 11010000 10111000 00101101 01101011 00011101 00111101

05:11100011 00001001 11010000 10111000 00101101 01101011 00011101 00111101

06:10100110 01000000 10111000 11100110 11100010 01101111 00101001 01111101

07:11110101 00011010 10110101 11100011 01010001 01110000 10100011 11001110

08:11100011 00001001 11010000 10111000 00101101 01101011 00011101 00111101

09:11111000 10100101 00010010 10011010 00010111 01100111 11111101 00010100

10:11100011 00001001 11010000 10111000 00101101 01101011 00011101 00111101

11:10010100 00011100 10110000 01001110 00110010 01111101 00000100 01101111

         通过对类似的一百组数据进行比较和分析,密钥改变一位,密文改变的位数分别有28位、34位、34位、39位、0位、27位、31位、33位、25位、24位等等。

通过一系列的测试,对密钥改变一位,密文的位数改变范围为0~34,密钥改变一位而密文不改变的概率几乎为零,改变位数在20位以上的占95%以上。

下面对密钥改变两位测试,

    例:明文20082374

密钥:1:abcdefgh ,2:bacdefgh 3: abdcefgh 4:abcdefhg5:abcdffgh6:abccdfgh

7:abbdefhh8:abbdefgg9:acddefgh10:abcddegh11:abcceegh

密文:

01:11100011 00001001 11010000 10111000 00101101 01101011 00011101 00111101

02:01101001 01111100 10001101 00111010 00101110 01000011 11000101 00011110

03:00001010 11010100 11010101 10001100 00010010 00011001 10101000 10101000

04:11110101 00011010 10110101 11100011 01010001 01110000 10100011 11001110

05:01010001 01011000 10001011 00101110 01111010 10010011 01001001 01100111

06:10111010 00110111 10101110 01001101 11001101 01000011 01010111 00011110

07:11111000 10100101 00010010 10011010 00010111 01100111 11111101 00010100

08:10100110 01000000 10111000 11100110 11100010 01101111 00101001 01111101

09:00010110 01011100 10100010 00100111 01101111 11100000 11110000 11000001

10:10010100 00011100 10110000 01001110 00110010 01111101 00000100 01101111

01:11100011 00001001 11010000 10111000 00101101 01101011 00011101 00111101

11:00011000 11010010 00001100 01101011 01011111 00110001 01001100 01001001

    通过对类似数据进行比较分析,对密钥改变2位,密文的位数变化情况为:26位、35位、35位、33位、32位、25位、25位、39位、30位、38位等。

对密钥改变两位,密文的位数改变范围为大致为:25~39位。

分析结果:

标准DES加密算法密文对密钥十分敏感,密文改变一位或者几位,都会是相应的密文改变二十几位,大部分情况下密文位数的改变在半数以上,也就是改变的位数超过32位。由于标准DES加密算法对于密钥十分敏感,所以使用这种算法加密的安全性取决于密钥,密钥的复杂程度和密钥的安全性决定了加密的数据的安全性。

编程体会

    通过这次课程设计,用程序实现了标准DES加密与解密算法。谈到编程体会与收获,最主要的一个收获就是对DES算法的深入理解和掌握。由于要编写代码实现DES算法,因此对于DES算法的每一个细节可以说是了如指掌了,每一个步骤总是推敲了一遍又一遍,找到最为简洁而清晰的实现方法。例如,在编写的过程中,我参考了一些网上的代码,那些代码在DES的十六轮加密与解密循环的实现上,竟然硬生生每一次循环写一次代码,为每一次循环中出现的变量定义了十六次,虽然思路清晰,确使得程序变得异常的庞大,增大很大的内存开销,使得程序执行的效率就不高。我在处理解密与解密的循环时,由于,第一次循环使用的数据是第一次分组的数据,与之后的数据在形式上相同,但表达上却不相同,因此,对于加密与解密的十六轮循环,我单独处理第一次循环,然后利用统一的表达方式和变量进行余下的十五轮循环,第十五轮循环结束的时候,就产生了用于产生密文或明文的最后的左部和右部数据。

    通过这次课程设计,另外一个收获就是提高了自己编程能力,在编程实现DES算法的时候,需要进行大量的代码编写工作,这使得我编写代码的能力有了大大的提高,差错纠错的能力也相应的得到了提高。

    最后是感谢和老师的教诲。


核心源代码

1、加密过程(JiaMi.cpp)

// JiaMi.cpp : implementation file

//

#include "stdafx.h"

#include "DES.h"

#include "JiaMi.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

#include "DESDlg.h"

/////////////////////////////////////////////////////////////////////////////

// JiaMi dialog

JiaMi::JiaMi(CWnd* pParent /*=NULL*/)

    : CDialog(JiaMi::IDD, pParent)

{

    //{{AFX_DATA_INIT(JiaMi)

    m_Mingwen = _T("");

    m_Miyao = _T("");

    m_Miwen = _T("");

    m_outputMiwen = _T("");

    //}}AFX_DATA_INIT

}

void JiaMi::DoDataExchange(CDataExchange* pDX)

{

    CDialog::DoDataExchange(pDX);

    //{{AFX_DATA_MAP(JiaMi)

    DDX_Control(pDX, IDC_LIST1, m_output);

    DDX_Text(pDX, IDC_Mingwen, m_Mingwen);

    DDX_Text(pDX, IDC_Miyao, m_Miyao);

    DDX_Text(pDX, IDC_Miwen, m_Miwen);

    DDX_Text(pDX, IDC_outMiwen, m_outputMiwen);

    //}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(JiaMi, CDialog)

    //{{AFX_MSG_MAP(JiaMi)

    ON_BN_CLICKED(IDC_back, Onback)

    ON_BN_CLICKED(IDC_JiaMi, OnJiaMi)

    //}}AFX_MSG_MAP

END_MESSAGE_MAP()

// JiaMi message handlers

BOOL JiaMi::OnInitDialog()

{

    CDialog::OnInitDialog();

    m_output.ModifyStyle(0,LVS_REPORT);

    DWORD style= m_output.GetExStyle();

    style=style^LVS_EX_CHECKBOXES;

    m_output.SetExtendedStyle(style|LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT);

    m_output.InsertColumn(0,"循环轮数",LVCFMT_LEFT,80);

    m_output.InsertColumn(1,"子密钥",LVCFMT_LEFT,450);

    m_output.InsertColumn(2,"左部(Li)",LVCFMT_LEFT,350);

    m_output.InsertColumn(3,"右部(Ri)",LVCFMT_LEFT,350);

    // TODO: Add extra initialization here

    return TRUE;  // return TRUE unless you set the focus to a control

                  // EXCEPTION: OCX Property Pages should return FALSE

}

void JiaMi::Onback()

{

    // TODO: Add your control notification handler code here

    ShowWindow(SW_HIDE);

    CDESDlg dlg;

    dlg.DoModal();

}

void JiaMi::OnJiaMi()

{

    // TODO: Add your control notification handler code here

    /*64位明文的输入:将明文和密钥转换成二进制并显示*/

    FILE *fp1,*fp2;

    int i,j,k;

    int str[8];

    char mingwen[8],miyao[8];       //存储从文件中读取的明文和密钥

    int mingwenB[64],miyaoB[64];    //存储64位二进制的明文和密钥

    fp1=fopen("data.txt","r");

    fp2=fopen("miyao.txt","r");

    if(fp1==NULL||fp2==NULL)

    {

       MessageBox("明文和密钥文件打开失败!");

       return;

    }

    for(i=0;i<8;i++)

    {

       fscanf(fp1,"%c",&mingwen[i]);

       fscanf(fp2,"%c",&miyao[i]);

    }

    fclose(fp1);

    fclose(fp2);

    FILE *fp4,*fp5;

    char ch;

    fp4=fopen("明文二进制.txt","w");

    fp5=fopen("密钥二进制.txt","w");

    k=0;

    for(i=0;i<8;i++)

    {

       ch=mingwen[i];

       for(j=0;j<8;j++)

       {

           str[j]=ch%2;

           ch=ch/2;

        }

       for(j=7;j>=0;j--)

       {

           mingwenB[k]=str[j];

           k++;

           fprintf(fp4,"%d",str[j]);

       }

    }

    fclose(fp4);

    k=0;

    for(i=0;i<8;i++)

    {

       ch=miyao[i];

       for(j=0;j<8;j++)

       {

           str[j]=ch%2;

           ch=ch/2;

       }

       for(j=7;j>=0;j--)

       {

           miyaoB[k]=str[j];

           k++;

           fprintf(fp5,"%d",str[j]);

       }

    }

    fclose(fp5);

    m_Mingwen="";

    for(i=0;i<64;i++)        //二进制明文显示在界面上

    {

       m_Mingwen=m_Mingwen+(char)(48+mingwenB[i]);

       if((i+1)%8==0)

           m_Mingwen=m_Mingwen+" ";

    }

    m_Miyao="";

    for(i=0;i<64;i++)        //二进制密钥显示在界面上

    {

       m_Miyao=m_Miyao+(char)(48+miyaoB[i]);

       if((i+1)%8==0)

           m_Miyao=m_Miyao+" ";

    }

    /*初始置换IP*/

    int IP_table[64]={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 afterIP[64];

    for(j=0;j<64;j++)

    {

       afterIP[j]=mingwenB[IP_table[j]-1];

    }

    /*明文的第零次分组,L0[32],R0[32]*/

    int L0[32],R0[32];

    for(i=0;i<32;i++)

       L0[i]=afterIP[i];

    for(j=0,i=32;i<64;i++,j++)

       R0[j]=afterIP[i];

    /*十六轮子密钥的生成*/

    int pc_1table[56]={             //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_2table[48]={             //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 afterpc_1[56];

    /*经过pc_1置换*/

    for(i=0;i<56;i++)

       afterpc_1[i]=miyaoB[pc_1table[i]-1];

    /*密钥第0次分组*/

    int C0[28],D0[28];

    for(i=0;i<28;i++)

       C0[i]=afterpc_1[i];

    for(j=0,i=28;i<56;i++,j++)

       D0[j]=afterpc_1[i];

    /*十六轮子密钥产生前的中间数据,左移产生的C[16][28],D[16][28]*/

    int C[16][28],D[16][28];

    for(i=0;i<27;i++)        //第一轮数据生成C[0][28]与D[0][28]

    {

       C[0][i]=C0[i+1];

       D[0][i]=D0[i+1];

    }

    C[0][27]=C0[0];

    D[0][27]=D0[0];

    for(i=1;i<16;i++)        //第二轮数据至第十六轮数据生成

    {   if(i==1||i==8||i==15)

       {   for(j=0;j<27;j++)           //左移1位

           {

              C[i][j]=C[i-1][j+1];

              D[i][j]=D[i-1][j+1];

           }

           C[i][27]=C[i-1][0];

           D[i][27]=D[i-1][0];

       }

       else

       {

           for(j=0;j<26;j++)

           {

              C[i][j]=C[i-1][j+2];

              D[i][j]=D[i-1][j+2];

           }

           C[i][26]=C[i-1][0];

           C[i][27]=C[i-1][1];

           D[i][26]=D[i-1][0];

           D[i][27]=D[i-1][1];

       }

    }

          

/*十六轮子密钥初始数据合并,为pc_2置换生成子密钥做准备*/

    int beforekey[16][56];

    k=0;

    for(i=0;i<16;i++)

    {

       for(j=0;j<28;j++)

           beforekey[i][j]=C[i][j];

       for(k=0;k<28;k++,j++)

           beforekey[i][j]=D[i][k];

    }

/*beforekey[16][56]经过pc_2置换,生成16轮子密钥key[16][48]*/

    int keys[16][48];

    for(i=0;i<16;i++)

       for(j=0;j<48;j++)

           keys[i][j]=beforekey[i][pc_2table[j]-1];

/*十六轮循环生成密文,首先是L[16][32]和R[16][32]的生成*/

    int L[16][32],R[16][32];

    int E_table[48]={

              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,31};

    int afterER0[48],beforeS[48];

    for(i=0;i<32;i++)    //Li=R(i-1)

       L[0][i]=R0[i];   

    for(i=0;i<48;i++)    //E置换,生成48位数据,与子密钥进行异或,为进入S盒做准备

       afterER0[i]=R0[E_table[i]-1];

    for(i=0;i<48;i++)

       if(afterER0[i]==keys[0][i])

           beforeS[i]=0;

       else

           beforeS[i]=1;

/*将beforeS[48]分在8个数组中,为经过8个S盒准备*/

    int beforeSBox[8][6];

    k=0;

    for(i=0;i<8;i++)

       for(j=0;j<6;j++)

       {

           beforeSBox[i][j]=beforeS[k];

           k++;

       }

/* S盒变换,48位数据生成32位数据*/

    int afterSBox[8];

    int SBox[8][4][16]={               //S盒变换表

              14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,

              0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,

              4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,

              15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13,

              15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,

              3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,

              0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,

              13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9,

              10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,

              13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,

              13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,

              1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12,

              7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,

              13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,

              10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,

              3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14,

              2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,

              14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,

              4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,

              11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3,

              12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,

              10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,

              9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,

              4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13,

              4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,

              13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,

              1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,

              6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12,

              13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,

              1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,

              7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,

                2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11};

    int hang,lie;

    for(i=0;i<8;i++)

    {

       hang=beforeSBox[i][0]*2+beforeSBox[i][5];

    lie=beforeSBox[i][1]*8+beforeSBox[i][2]*4+beforeSBox[i][3]*2+beforeSBox[i][4];

       afterSBox[i]=SBox[i][hang][lie];

    }

/*将从S盒中出来的8个十进制数字转换成32位的二进制数*/

    int beforep[32];

    k=0;

    int temp;

    int str1[4];

    for(i=0;i<8;i++)

    {

       temp=afterSBox[i];

       for(j=0;j<4;j++)

       {

           str1[j]=temp%2;

           temp=temp/2;

       }

       for(j=3;j>=0;j--)

       {

           beforep[k]=str1[j];

           k++;

       }

    }

/*从S盒输入的32位的二进制数进行P置换,生成的即是f函数的结果*/

    int p_table[32]={

              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 p[32];

    for(i=0;i<32;i++)

       p[i]=beforep[p_table[i]-1];

/*p[32]与L0[32]进行异或,得到R[0][32]*/

    for(i=0;i<32;i++)

    {

       R[0][i]=p[i]+L0[i];

       if(R[0][i]==2)

           R[0][i]=0;

    }

/*已经生成L[0][32]和R[0][32],下面进行十五轮循环,生成其余L[i][32]和R[i][32]*/

    int afterER[16][48];

    int n;

    for(i=1;i<16;i++)

    {

       for(j=0;j<32;j++)

           L[i][j]=R[i-1][j];

       for(j=0;j<48;j++)    //E置换

           afterER[i][j]=R[i-1][E_table[j]-1];

       for(j=0;j<48;j++)    //与子密钥进行异或

       {

           if(afterER[i][j]==keys[i][j])

              beforeS[j]=0;

           else

              beforeS[j]=1;

       }

       k=0;

       for(j=0;j<8;j++)  //生成进入S盒钱的8个数组,分别进入8个S盒

           for(n=0;n<6;n++)

           {

              beforeSBox[j][n]=beforeS[k];

              k++;

           }

       for(j=0;j<8;j++)     //进入S盒,从8个S盒中生成8个数

       {

           hang=beforeSBox[j][0]*2+beforeSBox[j][5];

           lie=beforeSBox[j][1]*8+beforeSBox[j][2]*4+beforeSBox[j][3]*2+beforeSBox[j][4];

           afterSBox[j]=SBox[j][hang][lie];

       }

       k=0;

       for(j=0;j<8;j++)  //S盒出来的8个十进制数转换成32位的二进制数

       {

           temp=afterSBox[j];

           for(n=0;n<4;n++)

           {

              str1[n]=temp%2;

              temp=temp/2;

           }

           for(n=3;n>=0;n--)

           {

              beforep[k]=str1[n];

              k++;

           }

       }

       for(j=0;j<32;j++)

           p[j]=beforep[p_table[j]-1];

       for(j=0;j<32;j++)

           if(p[j]==L[i-1][j])

              R[i][j]=0;

           else

              R[i][j]=1;

    }

/*通过十五轮循环,最后得到L[15][32]和R[15][32],合并之后进行IP逆置换生成密文*/

    int beforeoutput[64];

    int output[64];

    int IPR_tabel[64]={

                  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};

    for(i=0;i<32;i++)    //数据合并,R[15][32]在前,L[15][32]在后面

       beforeoutput[i]=R[15][i];

    for(i=32,j=0;i<64;i++,j++)

       beforeoutput[i]=L[15][j];

    for(i=0;i<64;i++)

       output[i]=beforeoutput[IPR_tabel[i]-1];//得到64位密文

    m_Miwen="";

    for(i=0;i<64;i++)    //将64位二进制密文输出到界面上

    {

       m_Miwen=m_Miwen+(char)(48+output[i]);

       if((i+1)%8==0)

           m_Miwen=m_Miwen+" ";

    }

/*将output[64]二进制密文转换成ASCII字符*/

    int charB[8][8];

    k=0;

    for(i=0;i<8;i++)

       for(j=0;j<8;j++)

       {

           charB[i][j]=output[k];

           k++;

       }

    char miwen[8];

    for(i=0;i<8;i++)

    {

       str[i]=0;

       if(charB[i][0]==1)

           str[i]=str[i]+128;

       if(charB[i][1]==1)

           str[i]=str[i]+64;

       if(charB[i][2]==1)

           str[i]=str[i]+32;

       if(charB[i][3]==1)

           str[i]=str[i]+16;

       if(charB[i][4]==1)

           str[i]=str[i]+8;

       if(charB[i][5]==1)

           str[i]=str[i]+4;

       if(charB[i][6]==1)

           str[i]=str[i]+2;

       if(charB[i][7]==1)

           str[i]=str[i]+1;

    }

    m_outputMiwen="";

    for(i=0;i<8;i++)

       miwen[i]=str[i];     //至此,得到密文miwen[8]

    miwen[i]='\0';

    m_outputMiwen=miwen;

    CString temp1,temp2,temp3;

    char *ch1,*ch2,*ch3;

    for(i=0;i<16;i++)

    {

       int m=m_output.InsertItem(0,"");

       char chtempL[40]="\0",chtempkey[55]="\0",chtempR[40]="\0",number[4]="\0";

       int ctempL[32],ctempkey[48],ctempR[32];

       for(j=0;j<32;j++)

       {

           ctempL[j]=L[i][j];

           ctempR[j]=R[i][j];

       }

       for(j=0;j<48;j++)

           ctempkey[j]=keys[i][j];

       for(j=0;j<32;j++)

       {

           temp1.Format("%d",ctempL[j]);

           ch1=temp1.GetBuffer(temp1.GetLength());

           strcat(chtempL,ch1);

           if((j+1)%8==0)

              strcat(chtempL," ");

           temp2.Format("%d",ctempR[j]);

           ch2=temp2.GetBuffer(temp2.GetLength());

           strcat(chtempR,ch2);

           if((j+1)%8==0)

              strcat(chtempR," ");

       }

       for(j=0;j<48;j++)

       {

           temp3.Format("%d",ctempkey[j]);

           ch3=temp3.GetBuffer(temp3.GetLength());

           strcat(chtempkey,ch3);

           if((j+1)%8==0)

              strcat(chtempkey," ");

       }

       _itoa(i+1,number,10);

       m_output.SetItemText(m,0,number);

       m_output.SetItemText(m,1,chtempkey);

       m_output.SetItemText(m,2,chtempL);

       m_output.SetItemText(m,3,chtempR);

    }

   

    UpdateData(false);

}

2、解密过程(JieMi.cpp)

// JieMi.cpp : implementation file

#include "stdafx.h"

#include "DES.h"

#include "JieMi.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

#include "DESDlg.h"

// JieMi dialog

JieMi::JieMi(CWnd* pParent /*=NULL*/)

    : CDialog(JieMi::IDD, pParent)

{

    //{{AFX_DATA_INIT(JieMi)

    m_Mingwen = _T("");

    m_Miwen = _T("");

    m_Miyao = _T("");

    m_outputMingwen = _T("");

    //}}AFX_DATA_INIT

}

void JieMi::DoDataExchange(CDataExchange* pDX)

{

    CDialog::DoDataExchange(pDX);

    //{{AFX_DATA_MAP(JieMi)

    DDX_Control(pDX, IDC_LIST1, m_output);

    DDX_Text(pDX, IDC_Mingwen, m_Mingwen);

    DDX_Text(pDX, IDC_Miwen, m_Miwen);

    DDX_Text(pDX, IDC_Miyao, m_Miyao);

    DDX_Text(pDX, IDC_outMingwen, m_outputMingwen);

    //}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(JieMi, CDialog)

    //{{AFX_MSG_MAP(JieMi)

    ON_BN_CLICKED(IDC_back, Onback)

    ON_BN_CLICKED(IDC_JieMi, OnJieMi)

    //}}AFX_MSG_MAP

END_MESSAGE_MAP()

// JieMi message handlers

BOOL JieMi::OnInitDialog()

{

    CDialog::OnInitDialog();

    m_output.ModifyStyle(0,LVS_REPORT);

    DWORD style= m_output.GetExStyle();

    style=style^LVS_EX_CHECKBOXES;

    m_output.SetExtendedStyle(style|LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT);

    m_output.InsertColumn(0,"循环轮数",LVCFMT_LEFT,80);

    m_output.InsertColumn(1,"子密钥",LVCFMT_LEFT,450);

    m_output.InsertColumn(2,"左部(Li)",LVCFMT_LEFT,350);

    m_output.InsertColumn(3,"右部(Ri)",LVCFMT_LEFT,350);

    // TODO: Add extra initialization here

    return TRUE;  // return TRUE unless you set the focus to a control

                  // EXCEPTION: OCX Property Pages should return FALSE

}

void JieMi::Onback()

{

    // TODO: Add your control notification handler code here

    ShowWindow(SW_HIDE);

    CDESDlg dlg;

    dlg.DoModal();

}

void JieMi::OnJieMi()

{

    // TODO: Add your control notification handler code here

    FILE *fp1,*fp2;

    int i,j,k;

    int str[8];

    char miwen[8],miyao[8];     //存储从文件中读取的明文和密钥

    int miwenB[64],miyaoB[64];  //存储64位二进制的明文和密钥

    fp1=fopen("data.txt","r");

    fp2=fopen("miyao.txt","r");

    if(fp1==NULL||fp2==NULL)

    {

       MessageBox("明文和密钥文件打开失败!");

       return;

    }

    for(i=0;i<8;i++)

    {

       fscanf(fp1,"%c",&miwen[i]);

       fscanf(fp2,"%c",&miyao[i]);

    }

    fclose(fp1);

    fclose(fp2);

    FILE *fp4,*fp5;

    char ch;

    fp4=fopen("密文二进制.txt","w");

    fp5=fopen("密钥二进制.txt","w");

    k=0;

    for(i=0;i<8;i++)

    {

       ch=miwen[i];

       for(j=0;j<8;j++)

       {

           str[j]=ch%2;

           ch=ch/2;

       }

       for(j=7;j>=0;j--)

       {

           miwenB[k]=str[j];

           k++;

           fprintf(fp4,"%d",str[j]);

       }

    }

    fclose(fp4);

    k=0;

    for(i=0;i<8;i++)

    {

       ch=miyao[i];

       for(j=0;j<8;j++)

       {

           str[j]=ch%2;

           ch=ch/2;

       }

       for(j=7;j>=0;j--)

       {

           miyaoB[k]=str[j];

           k++;

           fprintf(fp5,"%d",str[j]);

       }

    }

    fclose(fp5);

    char Miwentemp[75]="\0",Miyaotemp[75]="\0";

    CString temp1;

    char *cha;

    for(i=0;i<64;i++)

    {

       temp1.Format("%d",miwenB[i]);

       cha=temp1.GetBuffer(temp1.GetLength());

       strcat(Miwentemp,cha);

       if((i+1)%8==0)

           strcat(Miwentemp," ");

    }

    m_Miwen=Miwentemp;       //二进制密文显示在界面上

    for(i=0;i<64;i++)

    {

       temp1.Format("%d",miyaoB[i]);

       cha=temp1.GetBuffer(temp1.GetLength());

       strcat(Miyaotemp,cha);

       if((i+1)%8==0)

           strcat(Miyaotemp," ");

    }

    m_Miyao=Miyaotemp;       //二进制密钥显示在界面上

/*密钥的生成*/

    int pc_1table[56]={             //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_2table[48]={             //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 afterpc_1[56];

/*经过pc_1置换*/

    for(i=0;i<56;i++)

       afterpc_1[i]=miyaoB[pc_1table[i]-1];

           /*密钥第0次分组*/

    int C0[28],D0[28];

    for(i=0;i<28;i++)

       C0[i]=afterpc_1[i];

    for(j=0,i=28;i<56;i++,j++)

       D0[j]=afterpc_1[i];

/*十六轮子密钥产生前的中间数据,左移产生的C[16][28],D[16][28]*/

    int C[16][28],D[16][28];

    for(i=0;i<27;i++)        //第一轮数据生成C[0][28]与D[0][28]

       {

           C[0][i]=C0[i+1];

           D[0][i]=D0[i+1];

       }

    C[0][27]=C0[0];

    D[0][27]=D0[0];

    for(i=1;i<16;i++)        //第二轮数据至第十六轮数据生成

       {  

           if(i==1||i==8||i==15)

           {  

              for(j=0;j<27;j++)           //左移1位

              {

                  C[i][j]=C[i-1][j+1];

                  D[i][j]=D[i-1][j+1];

              }

              C[i][27]=C[i-1][0];

              D[i][27]=D[i-1][0];

           }

           else                     //左移2位

           {

              for(j=0;j<26;j++)

              {

                  C[i][j]=C[i-1][j+2];

                  D[i][j]=D[i-1][j+2];

              }

              C[i][26]=C[i-1][0];

              C[i][27]=C[i-1][1];

              D[i][26]=D[i-1][0];

              D[i][27]=D[i-1][1];

           }

       }

          

/*十六轮子密钥初始数据合并,为pc_2置换生成子密钥做准备*/

    int beforekey[16][56];

    k=0;

    for(i=0;i<16;i++)

       {

           for(j=0;j<28;j++)

              beforekey[i][j]=C[i][j];

           for(k=0;k<28;k++,j++)

              beforekey[i][j]=D[i][k];

       }

/*beforekey[16][56]经过pc_2置换,生成16轮子密钥key[16][48]*/

    int keys[16][48];

    for(i=0;i<16;i++)

       for(j=0;j<48;j++)

           keys[i][j]=beforekey[i][pc_2table[j]-1];

/*初始置换IP*/

    int IP_table[64]={

                  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 afterIP[64];

    for(i=0;i<64;i++)

    {

       afterIP[i]=miwenB[IP_table[i]-1];

    }

    /*明文的第零次分组,L0[32],R0[32]*/

    int L0[32],R0[32];

    for(i=0;i<32;i++)

       L0[i]=afterIP[i];

    for(j=0,i=32;i<64;i++,j++)

       R0[j]=afterIP[i];

    /*十六轮循环生成密文,首先是L[16][32]和R[16][32]的生成*/

    int L[16][32],R[16][32];

    int E_table[48]={

              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,31};

    int afterER0[48],beforeS[48];

    for(i=0;i<32;i++)    //Li=R(i-1)

       L[0][i]=R0[i];   

    for(i=0;i<48;i++)    //E置换,生成48位数据,与第十五轮子密钥进行异或,为进入S盒做准备

       afterER0[i]=R0[E_table[i]-1];

    for(i=0;i<48;i++)

       if(afterER0[i]==keys[15][i])

           beforeS[i]=0;

       else

           beforeS[i]=1;

/*将beforeS[48]分在8个数组中,为经过8个S盒准备*/

    int beforeSBox[8][6];

    k=0;

    for(i=0;i<8;i++)

       for(j=0;j<6;j++)

       {

           beforeSBox[i][j]=beforeS[k];

           k++;

       }

/* S盒变换,48位数据生成32位数据*/

    int afterSBox[8];

    int SBox[8][4][16]={               //S盒变换表

              14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,

              0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,

              4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,

              15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13,

              15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,

              3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,

              0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,

              13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9,

              10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,

              13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,

              13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,

              1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12,

              7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,

              13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,

              10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,

              3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14,

              2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,

              14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,

              4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,

              11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3,

              12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,

              10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,

              9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,

               4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13,

              4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,

              13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,

              1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,

              6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12,

              13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,

               1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,

              7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,

                2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11};

    int hang,lie;

    for(i=0;i<8;i++)

    {

       hang=beforeSBox[i][0]*2+beforeSBox[i][5];

    lie=beforeSBox[i][1]*8+beforeSBox[i][2]*4+beforeSBox[i][3]*2+beforeSBox[i][4];

       afterSBox[i]=SBox[i][hang][lie];

    }

/*将从S盒中出来的8个十进制数字转换成32位的二进制数*/

    int beforep[32];

    k=0;

    int temp;

    int str1[4];

    for(i=0;i<8;i++)

    {

       temp=afterSBox[i];

       for(j=0;j<4;j++)

       {

           str1[j]=temp%2;

           temp=temp/2;

       }

       for(j=3;j>=0;j--)

       {

           beforep[k]=str1[j];

           k++;

       }

    }

/*从S盒输入的32位的二进制数进行P置换,生成的即是f函数的结果*/

    int p_table[32]={

              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 p[32];

    for(i=0;i<32;i++)

       p[i]=beforep[p_table[i]-1];

/*p[32]与L0[32]进行异或,得到R[0][32]*/

    for(i=0;i<32;i++)

    {

       R[0][i]=p[i]+L0[i];

       if(R[0][i]==2)

           R[0][i]=0;

    }

/*已经生成L[0][32]和R[0][32],下面进行十五轮循环,生成其余L[i][32]和R[i][32]*/

    int afterER[16][48];

    int n;

    for(i=1;i<16;i++)

    {

       for(j=0;j<32;j++)

           L[i][j]=R[i-1][j];

       for(j=0;j<48;j++)    //E置换

           afterER[i][j]=R[i-1][E_table[j]-1];

       for(j=0;j<48;j++)    //与子密钥进行异或

       {

           if(afterER[i][j]==keys[15-i][j])

              beforeS[j]=0;

           else

              beforeS[j]=1;

        }

       k=0;

       for(j=0;j<8;j++)  //生成进入S盒钱的8个数组,分别进入8个S盒

           for(n=0;n<6;n++)

           {

              beforeSBox[j][n]=beforeS[k];

              k++;

           }

       for(j=0;j<8;j++)     //进入S盒,从8个S盒中生成8个数

       {

           hang=beforeSBox[j][0]*2+beforeSBox[j][5];

           lie=beforeSBox[j][1]*8+beforeSBox[j][2]*4+beforeSBox[j][3]*2+beforeSBox[j][4];

           afterSBox[j]=SBox[j][hang][lie];

       }

       k=0;

       for(j=0;j<8;j++)  //S盒出来的8个十进制数转换成32位的二进制数

       {

           temp=afterSBox[j];

           for(n=0;n<4;n++)

           {

              str1[n]=temp%2;

              temp=temp/2;

           }

           for(n=3;n>=0;n--)

           {

              beforep[k]=str1[n];

              k++;

           }

       }

       for(j=0;j<32;j++)

           p[j]=beforep[p_table[j]-1];

       for(j=0;j<32;j++)

           if(p[j]==L[i-1][j])

              R[i][j]=0;

           else

              R[i][j]=1;

    }

/*通过十五轮循环,最后得到L[15][32]和R[15][32],合并之后进行IP逆置换生成明文*/

    int beforeoutput[64];

    int output[64];

    int IPR_tabel[64]={

                  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};

    for(i=0;i<32;i++)    //数据合并,R[15][32]在前,L[15][32]在后面

       beforeoutput[i]=R[15][i];

    for(i=32,j=0;i<64;i++,j++)

       beforeoutput[i]=L[15][j];

    for(i=0;i<64;i++)

       output[i]=beforeoutput[IPR_tabel[i]-1];//得到64位明文

    m_Mingwen="";

    for(i=0;i<64;i++)

    {

       m_Mingwen=m_Mingwen+(char)(48+output[i]);

       if((i+1)%8==0)

           m_Mingwen=m_Mingwen+" ";        //64位明文显示在界面上

    }

    int charB[8][8];

    k=0;

    for(i=0;i<8;i++)

    {

       for(j=0;j<8;j++,k++)

           charB[i][j]=output[k];

    }

    char result[8];

    for(i=0;i<8;i++)

    {

       str[i]=0;

       if(charB[i][0]==1)

           str[i]=str[i]+128;

       if(charB[i][1]==1)

           str[i]=str[i]+64;

       if(charB[i][2]==1)

           str[i]=str[i]+32;

       if(charB[i][3]==1)

           str[i]=str[i]+16;

       if(charB[i][4]==1)

           str[i]=str[i]+8;

       if(charB[i][5]==1)

           str[i]=str[i]+4;

       if(charB[i][6]==1)

           str[i]=str[i]+2;

       if(charB[i][7]==1)

           str[i]=str[i]+1;

    }

    for(i=0;i<8;i++)

       result[i]=str[i];

    result[i]='\0';

    m_outputMingwen=result;

    CString temp2,temp3;

    char *ch1,*ch2,*ch3;

    for(i=0;i<16;i++)

    {

       int m=m_output.InsertItem(0,"");

       char chtempL[40]="\0",chtempkey[55]="\0",chtempR[40]="\0",number[4]="\0";

       int ctempL[32],ctempkey[48],ctempR[32];

       for(j=0;j<32;j++)

       {

           ctempL[j]=R[i][j];

           ctempR[j]=L[i][j];

       }

       for(j=0;j<48;j++)

           ctempkey[j]=keys[i][j];

       for(j=0;j<32;j++)

       {

           temp1.Format("%d",ctempL[j]);

           ch1=temp1.GetBuffer(temp1.GetLength());

           strcat(chtempL,ch1);

           if((j+1)%8==0)

              strcat(chtempL," ");

           temp2.Format("%d",ctempR[j]);

           ch2=temp2.GetBuffer(temp2.GetLength());

           strcat(chtempR,ch2);

           if((j+1)%8==0)

              strcat(chtempR," ");

       }

       for(j=0;j<48;j++)

       {

           temp3.Format("%d",ctempkey[j]);

           ch3=temp3.GetBuffer(temp3.GetLength());

           strcat(chtempkey,ch3);

           if((j+1)%8==0)

              strcat(chtempkey," ");

       }

       _itoa(i+1,number,10);

       m_output.SetItemText(m,0,number);

       m_output.SetItemText(m,1,chtempkey);

       m_output.SetItemText(m,2,chtempL);

       m_output.SetItemText(m,3,chtempR);

    }

UpdateData(false);

   

}

相关推荐