分工已完成,今天可以开始Coding了,距离成功又近了一步。
具体说下S盒的原理:
S盒会将48位的输入重新变为32为,所以P是一个从32位到32位的置换,其具体置换规则如下图所示:

DES算法的核心部分就是S盒,其结构如下图所示:

48位的输入分为8组,每组6位输入到一个小S盒(S(i))中,每个S(i)将8位输入压缩变换为4位,8个S(i)的输出形成32位的S盒输出。
每个S(i)的变换方法为(此处考虑S(1)):设S(1)的输入为b1b2b3b4b5b6,用b1b6对应的10进制数作为行号,用b2b3b4b5对应的10进制数作为列号查找下表,得到的数对应的二进制就是S(1)的输出结果。
现将代码贴下,稚嫩的代码。
// Shorten.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
using namespace std;
const int nSboxOutput = 32;
const int nBlocklength = 6;
char *arrnS1[][16] = {{"1110","0100","1101","0001","0010","1111","1011","1000","0011","1010","0110","1100","0101","1001","0000","0111"},
{"0000","1111","0111","0100","1110","0010","1101","0001","1010","0110","1100","1011","1001","0101","0011","1000"},
{"0100","0001","1110","1000","1101","0110","0010","1101","1111","1100","1001","0111","0011","1010","0101","0000"},
{"1111","1100","1000","0010","0100","1001","0001","0111","0101","1101","0011","1110","1010","0000","0110","1101"}
};
char *arrnS2[][16] = {{"1111","0001","1000","1110","0110","1011","0011","0100","1001","0111","0010","1101","1100","0000","0101","1010"},
{"0011","1101","0100","0111","1111","0010","1000","1110","1100","0000","0001","1010","0110","1001","1011","0101"},
{"0000","1110","0111","1011","1010","0100","1101","0001","0101","1000","1100","0110","1001","0011","0010","1111"},
{"1101","1000","1010","0001","0011","1111","0100","0010","1011","0110","0111","1100","0000","0101","1110","1001"}
};
char *arrnS3[][16] = {{"1010","0000","1001","1110","0110","0011","1111","0101","0001","1101","1100","0111","1011","0100","0010","1000"},
{"1101","0111","0000","1001","0011","0100","0110","1010","0010","1000","0101","1110","1100","1011","1111","0001"},
{"1101","0110","0100","1001","1000","1111","0011","0000","1011","0001","0010","1100","0101","1010","1110","0111"},
{"0001","1010","1101","0000","0110","1001","1000","0111","0100","1111","1110","0011","1011","0101","0010","1100"}
};
char *arrnS4[][16] = {{"0111","1101","1110","0011","0000","0110","1001","1010","0001","0010","1000","0101","1011","1100","0100","1111"},
{"1101","1000","1011","0101","0110","1111","0000","0011","0100","0111","0010","1100","0001","1010","1110","1001"},
{"1010","0110","1001","0000","1100","1011","0111","1101","1111","0001","0011","1110","0101","0010","1000","0100"},
{"0011","1111","0000","0110","1010","0001","1101","1000","1001","0100","0101","1011","1100","0111","0010","1110"}
};
char *arrnS5[][16] = {{"0010","1100","0100","0001","0111","1010","1011","0110","1000","0101","0011","1111","1101","0000","1110","1001"},
{"1110","1011","0010","1100","0100","0111","1101","0001","0101","0000","1111","1010","0011","1001","1000","0110"},
{"0100","0010","0001","1011","1010","1101","0111","1000","1111","1001","1100","0101","0110","0011","0000","1110"},
{"1011","1000","1100","0001","0001","1110","0010","1101","0110","1111","0000","1001","1010","0100","0101","0011"}
};
char *arrnS6[][16] = {{"1100","0001","1110","1111","1001","0010","0110","1000","0000","1101","0011","0100","1110","0111","0101","1011"},
{"1010","1111","0100","0010","0111","1100","1001","0101","0110","0001","1101","1110","0000","1011","0011","1000"},
{"1001","1110","1111","0101","0010","1000","1100","0011","0111","0000","0100","1010","0001","1101","1011","0110"},
{"0100","0011","0010","1100","1001","0101","1111","1010","1011","1110","0001","0111","0110","0000","1000","1101"}
};
char *arrnS7[][16] = {{"0100","1011","0010","1110","1110","0000","1000","1101","0011","1100","1001","0111","0101","1010","0110","0001"},
{"1101","0000","1011","0111","0100","1001","0001","1010","1110","0011","0101","1100","0010","1111","1000","0110"},
{"0001","0100","1011","1101","1100","0011","0111","1110","1010","1111","0110","1000","0000","0101","1001","0010"},
{"0110","1011","1101","1000","0001","0100","1010","0111","1001","0101","0000","1111","1110","0010","0011","1100"}
};
char *arrnS8[][16] = {{"1101","0010","1000","0100","0110","1111","1011","0001","1010","1001","0011","1110","0101","0000","1100","0111"},
{"0001","1111","1101","1000","1010","0011","0111","0100","1100","0101","0110","1011","0000","1110","1001","0010"},
{"0111","1011","0100","0001","1001","1100","1110","0010","0000","0110","1010","1101","1111","0011","0101","1000"},
{"0010","0001","1110","0111","0100","1010","1000","1101","1111","1100","1001","0000","0011","0101","0110","1011"}
};
int test[] = {0,0,1,1,0,1,1,0,
1,1,1,1,1,0,0,1,
0,1,1,0,1,1,1,0,
1,1,0,1,0,1,0,1,
1,0,0,0,1,1,0,0,
0,1,1,0,0,1,1,0
};
int * parrnShorten(int * parrnTmp);
int main()
{
int *tmp = new int[32];
tmp = parrnShorten(test);
for (int i = 0;i < 32;i++)
cout << tmp[i] << "\t";
delete(tmp);
return 0;
}
int * parrnShorten(int * parrnTmp)
{
int nStrtobinary(string str);
int nRowvalue,nColvalue,nBlockfirst = 0;
char strTmp[4];
char strRow[2];
char strCol[4];
int * parrnPlaintext32 = new int[nSboxOutput];
int nRow,nCol;
int nOutcounter = 0;
int nLoopcounter = 0;
int nBlock = 0;
const int nBlocknum = 8;
for (nBlock = 0;nBlock < nBlocknum;nBlock++,nBlockfirst += nBlocklength)
{
nRowvalue = parrnTmp[nBlockfirst] * 10 + parrnTmp[nBlockfirst + nBlocklength - 1];
nColvalue = parrnTmp[nBlockfirst + 1] * 1000 + parrnTmp[nBlockfirst + 2] * 100 + parrnTmp[nBlockfirst + 3] * 10 + parrnTmp[nBlockfirst + 4];
itoa(nRowvalue,strRow,10);
itoa(nColvalue,strCol,10);
nRow = nStrtobinary(strRow);
nCol = nStrtobinary(strCol);
switch (nBlock)
{
case 0:
strcpy(strTmp,arrnS1[nRow][nCol]);
break;
case 1:
strcpy(strTmp,arrnS2[nRow][nCol]);
break;
case 2:
strcpy(strTmp,arrnS3[nRow][nCol]);
break;
case 3:
strcpy(strTmp,arrnS4[nRow][nCol]);
break;
case 4:
strcpy(strTmp,arrnS5[nRow][nCol]);
break;
case 5:
strcpy(strTmp,arrnS6[nRow][nCol]);
break;
case 6:
strcpy(strTmp,arrnS7[nRow][nCol]);
break;
case 7:
strcpy(strTmp,arrnS8[nRow][nCol]);
break;
}
for (nLoopcounter = 0;nLoopcounter < 4 && nOutcounter < nSboxOutput;nLoopcounter++,nOutcounter++)
{
parrnPlaintext32[nOutcounter] = strTmp[nLoopcounter] - '0';
}
}
return parrnPlaintext32;
}
int nStrtobinary(string str)
{
int nLength = str.size();
int nLoop = 0;
char chCharati;
int nBinary = 0;
for (nLoop = 0;nLoop < nLength;nLoop++)
{
chCharati = str[nLoop] - '0';
if (chCharati == 1)
nBinary += (int)pow(2.0,nLength-nLoop-1);
else if (chCharati == 0)
continue;
else
{
printf("原数据不是二进制数!\n");
exit(0);
}
}
return nBinary;
}