// DES.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "math.h"
struct Sbox
{
int element[64];
}S_box[8]={ {14, 0, 4,15,13, 7, 1, 4, 2,14,15, 2,11,13, 8, 1, //0
3,10,10, 6, 6,12,12,11, 5, 9, 9, 5, 0, 3, 7, 8,
4,15, 1,12,14, 8, 8, 2,13, 4, 6, 9, 2, 1,11, 7,
15, 5,12,11, 9, 3, 7,14, 3,10,10, 0, 5, 6, 0,13},
{15, 3, 1,13, 8, 4,14, 7, 6,15,11, 2, 3, 8, 4,14, //1
9,12, 7, 0, 2, 1,13,10,12, 6, 0, 9, 5,11,10, 5,
0,13,14, 8, 7,10,11, 1,10, 3, 4,15,13, 4, 1, 2,
5,11, 8, 6,12, 7, 6,12, 9, 0, 3, 5, 2,14,15, 9},
{10,13, 0, 7, 9, 0,14, 9, 6, 3, 3, 4,15, 6, 5,10, //2
1, 2,13, 8,12, 5, 7,14,11,12, 4,11, 2,15, 8, 1,
13, 1, 6,10, 4,13, 9, 0, 8, 6,15, 9, 3, 8, 0, 7,
11, 4, 1,15, 2,14,12, 3, 5,11,10, 5,14, 2, 7,12},
{ 7,13,13, 8,14,11, 3, 5, 0, 6, 6,15, 9, 0,10, 3, //3
1, 4, 2, 7, 8, 2, 5,12,11, 1,12,10, 4,14,15, 9,
10, 3, 6,15, 9, 0, 0, 6,12,10,11, 1, 7,13,13, 8,
15, 9, 1, 4, 3, 5,14,11, 5,12, 2, 7, 8, 2, 4,14},
{ 2,14,12,11, 4, 2, 1,12, 7, 4,10, 7,11,13, 6, 1, //4
8, 5, 5, 0, 3,15,15,10,13, 3, 0, 9,14, 8, 9, 6,
4,11, 2, 8, 1,12,11, 7,10, 1,13,14, 7, 2, 8,13,
15, 6, 9,15,12, 0, 5, 9, 6,10, 3, 4, 0, 5,14, 3},
{12,10, 1,15,10, 4,15, 2, 9, 7, 2,12, 6, 9, 8, 5, //5
0, 6,13, 1, 3,13, 4,14,14, 0, 7,11, 5, 3,11, 8,
9, 4,14, 3,15, 2, 5,12, 2, 9, 8, 5,12,15, 3,10,
7,11, 0,14, 4, 1,10, 7, 1, 6,13, 0,11, 8, 6,13},
{ 4,13,11, 0, 2,11,14, 7,15, 4, 0, 9, 8, 1,13,10, // 6
3,14,12, 3, 9, 5, 7,12, 5, 2,10,15, 6, 8, 1, 6,
1, 6, 4,11,11,13,13, 8,12, 1, 3, 4, 7,10,14, 7,
10, 9,15, 5, 6, 0, 8,15, 0,14, 5, 2, 9, 3, 2,12},
{13, 1, 2,15, 8,13, 4, 8, 6,10,15, 3,11, 7, 1, 4, //7
10,12, 9, 5, 3, 6,14,11, 5, 0, 0,14,12, 9, 7, 2,
7, 2,11, 1, 4,14, 1, 7, 9, 4,12,10,14, 8, 2,13,
0,15, 6,12,10, 9,13, 0,15, 3, 3, 5, 5, 6, 8,11}};
////////////////////////////////////////////////////////////////////////////////////////////
/* 获取密钥 */
/*--------------------------------------------------*/
//从Key.txt中获取64位的密钥存pKey指向的数组
void GetKey( char *pKey )
{
struct Key8bit
{
unsigned a: 4; //注意ab不能互换
unsigned b: 4;
};
union
{
struct Key8bit Keyc;
char c;
}union1;
int i;
FILE *fp;
char tempc1,tempc2;
fp=fopen("Key.txt","rb");
for( i=0 ; i<8 ; i++ )
{
tempc1=fgetc(fp);
if(tempc1>='0' && tempc1<='9')
{
union1.Keyc.b=tempc1-48;
}
else if(tempc1>='a' && tempc1<='f')
{
union1.Keyc.b=tempc1-87;
}
else
{
union1.Keyc.b=tempc1-55;
}
tempc2=fgetc(fp);
if(tempc2>='0' && tempc2<='9')
{
union1.Keyc.a=tempc2-48;
}
else if(tempc1>='a' && tempc1<='f')
{
union1.Keyc.a=tempc2-87;
}
else
{
union1.Keyc.a=tempc2-55;
}
*(pKey+i)=union1.c;
}
fclose(fp);
}
/* 获取比特值 */
/*--------------------------------------------------*/
//pKey 指针指向数组
//i 表示要获取的第几比特位的值
//返回int型 1 或 0
int GetBitValue(char *pch , int i )
{
int flag;
struct Byte
{
unsigned bit7: 1;
unsigned bit6: 1;
unsigned bit5: 1;
unsigned bit4: 1;
unsigned bit3: 1;
unsigned bit2: 1;
unsigned bit1: 1;
unsigned bit0: 1;
};
union
{
struct Byte OneByte;
char Tempc;
}C;
C.Tempc = *(pch+(i/8));
switch( (i%8) )
{
case 0: {
if(C.OneByte.bit0 == 0)
flag = 0;
else flag = 1;
break;
}
case 1: {
if(C.OneByte.bit1 == 0)
flag = 0;
else flag = 1;
break;
}
case 2: {
if(C.OneByte.bit2 == 0)
flag = 0;
else flag = 1;
break;
}
case 3: {
if(C.OneByte.bit3 == 0)
flag = 0;
else flag = 1;
break;
}
case 4: {
if(C.OneByte.bit4 == 0)
flag = 0;
else flag = 1;
break;
}
case 5: {
if(C.OneByte.bit5 == 0)
flag = 0;
else flag = 1;
break;
}
case 6: {
if(C.OneByte.bit6 == 0)
flag = 0;
else flag = 1;
break;
}
case 7: {
if(C.OneByte.bit7 == 0)
flag = 0;
else flag = 1;
break;
}
}
return flag;
}
/* 设置比特位 */
/*--------------------------------------------------*/
//pKeyPC1 指针指向char型数组
//i 表示数组的第几比特位要设置
//flag int型1或0 表示第i位的比特位设置值
void SetBitValue(char *pKeyPC1 , int i , int flag)
{
struct Byte
{
unsigned bit7: 1;
unsigned bit6: 1;
unsigned bit5: 1;
unsigned bit4: 1;
unsigned bit3: 1;
unsigned bit2: 1;
unsigned bit1: 1;
unsigned bit0: 1;
};
union
{
struct Byte OneByte;
char Tempc;
}C;
C.Tempc = *(pKeyPC1+(i/8));
switch( (i%8) )
{
case 0: C.OneByte.bit0 = flag; break;
case 1: C.OneByte.bit1 = flag; break;
case 2: C.OneByte.bit2 = flag; break;
case 3: C.OneByte.bit3 = flag; break;
case 4: C.OneByte.bit4 = flag; break;
case 5: C.OneByte.bit5 = flag; break;
case 6: C.OneByte.bit6 = flag; break;
case 7: C.OneByte.bit7 = flag; break;
}
*(pKeyPC1+(i/8)) = C.Tempc;
}
/* 置换选择一 */
/*--------------------------------------------------*/
// 输入8字节的字符数组指针 pKey
// 输出到7字节的数组里 pKeyPC1
void PermutedChoice1( char *pKeyPC1 , char *pKey )
{
int i;
int PC_1[56]={56,48,40,32,24,16, 8, 0,57,49,41,33,25,17,
9, 1,58,50,42,34,26, 18,10, 2,59,51,43,35,
// 62,54,46,38,30,22,14,6,61,53,45,37,29,21,
// 13,5, 60, 52,44,36,28,20,12,4,27,19,11,3};
27,19,11, 3,60,52,44, 36,28,20,12, 4,61,53,
45,37,29,21,13, 5,62, 54,46,38,30,22,14, 6};
int flag;
for(i=0 ; i<56 ; i++)
{
flag = GetBitValue(pKey , PC_1[i] );
SetBitValue(pKeyPC1 , i , flag);
}
}
/* 循环移位 */
/*--------------------------------------------------*/
// 输入pC pD 移位数 LS
// 输出移位后的pC pD
void LeftShift(int LS, char *pKey)
{
int i;
int tempflag;
int flag;
for( ; LS>0 ; LS--)
{
tempflag = GetBitValue(pKey , 0);
for(i=0 ; i<27 ; i++)
{
flag = GetBitValue(pKey , i+1);
SetBitValue(pKey , i , flag);
}
SetBitValue(pKey , 27 , tempflag);
}
}
/* 置换选择二 */
/*--------------------------------------------------*/
void PermutedChoice2(char *pSubKey , int i , char *pKeyC , char *pKeyD)
{
int indexPC2[48]={ 13,16,10,23, 0, 4, 2,27,14, 5,20, 9,22,18,11, 3,
25, 7,15, 6,26,19,12, 1,40,51,30,36,46,54,29,39,
50,44,32,47,43,48,38,55,33,52,45,41,49,35,28,31};
int m;
int flag;
for(m=0 ; m<48 ; m++)
{
if(indexPC2[m] < 28)
{
flag = GetBitValue(pKeyC , indexPC2[m]);
}
else
{
flag = GetBitValue(pKeyD , indexPC2[m]-28);
}
SetBitValue(pSubKey , i*48+m , flag);
}
}
/* 产生16子密钥 */
/*--------------------------------------------------*/
// 输入pC pD
// 输出16个子密钥
void ProcessSubkey(char *pSubKey , char *pKeyC , char *pKeyD)
{
int LS[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; //循环左移
int i;
for(i=0 ; i<16 ; i++)
{
LeftShift(LS[i] , pKeyC);
LeftShift(LS[i] , pKeyD);
PermutedChoice2(pSubKey , i , pKeyC , pKeyD);
}
}
/*--------------分割置换选择一后的密钥--------------*/
/*--------------------------------------------------*/
void SplitPermutedKey(char *pKeyC , char *pKeyD , char *pKeyPC1 )
{
int i;
int j;
int flag;
for(i=0 ; i<28 ; i++)
{
flag = GetBitValue(pKeyPC1 , i );
SetBitValue(pKeyC , i , flag);
}
for(j=0 ; i<56 ; i++,j++)
{
flag = GetBitValue(pKeyPC1 , i);
SetBitValue(pKeyD , j , flag);
}
}
/* 获取待加密的数据 */
/*--------------------------------------------------*/
void GetData( char *pData )
{
*(pData+0)='l';
*(pData+1)='e';
*(pData+2)='a';
*(pData+3