📄 mydes.cpp
字号:
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char U08;
typedef unsigned long U32;
static U32 wz_leftandtab[3] = {0x0 , 0x80000000 , 0xc0000000 } ;
//****密钥移位表******************************************************
static U08 wz_lefttable[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
//********************************************************************
//****密钥初始置换表************************
static U08 wz_keyleft[28] = {
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
};
static U08 wz_keyright[28] ={
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
};
//**************************************************
//****56位密钥选取48位密钥表********************************
static U08 wz_keychoose[48] ={
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
};
//**********************************************************
//****64位数据初始置换表***************************
static U08 wz_pc1[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
} ;
//**********************************************************
//****right由32位扩展成48位表*********************
static U08 exptab3[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,1
};
//********************************************************
static U32 wz_pc2[64] ={
0x80000000L,0x40000000L,0x20000000L,0x10000000L,
0x8000000L, 0x4000000L, 0x2000000L, 0x1000000L,
0x800000L, 0x400000L, 0x200000L, 0x100000L,
0x80000L, 0x40000L, 0x20000L, 0x10000L,
0x8000L, 0x4000L, 0x2000L, 0x1000L,
0x800L, 0x400L, 0x200L, 0x100L,
0x80L, 0x40L, 0x20L, 0x10L,
0x8L, 0x4L, 0x2L, 0x1L,
0x80000000L,0x40000000L,0x20000000L,0x10000000L,
0x8000000L, 0x4000000L, 0x2000000L, 0x1000000L,
0x800000L, 0x400000L, 0x200000L, 0x100000L,
0x80000L, 0x40000L, 0x20000L, 0x10000L,
0x8000L, 0x4000L, 0x2000L, 0x1000L,
0x800L, 0x400L, 0x200L, 0x100L,
0x80L, 0x40L, 0x20L, 0x10L,
0x8L, 0x4L, 0x2L, 0x1L,
};
//****right由48位压缩成32位表**********************
static U08 SP[8][64] ={
{
0xe,0x0,0x4,0xf,0xd,0x7,0x1,0x4,
0x2,0xe,0xf,0x2,0xb,0xd,0x8,0x1, //0xb 0x1
0x3,0xa,0xa,0x6,0x6,0xc,0xc,0xb,
0x5,0x9,0x9,0x5,0x0,0x3,0x7,0x8,
0x4,0xf,0x1,0xc,0xe,0x8,0x8,0x2,
0xd,0x4,0x6,0x9,0x2,0x1,0xb,0x7,
0xf,0x5,0xc,0xb,0x9,0x3,0x7,0xe,
0x3,0xa,0xa,0x0,0x5,0x6,0x0,0xd
},
{
0xf,0x3,0x1,0xd,0x8,0x4,0xe,0x7,
0x6,0xf,0xb,0x2,0x3,0x8,0x4,0xf,
0x9,0xc,0x7,0x0,0x2,0x1,0xd,0xa,
0xc,0x6,0x0,0x9,0x5,0xb,0xa,0x5,
0x0,0xd,0xe,0x8,0x7,0xa,0xb,0x1,
0xa,0x3,0x4,0xf,0xd,0x4,0x1,0x2,
0x5,0xb,0x8,0x6,0xc,0x7,0x6,0xc,
0x9,0x0,0x3,0x5,0x2,0xe,0xf,0x9
},
{
0xa,0xd,0x0,0x7,0x9,0x0,0xe,0x9,
0x6,0x3,0x3,0x4,0xf,0x6,0x5,0xa,
0x1,0x2,0xd,0x8,0xc,0x5,0x7,0xe,
0xb,0xc,0x4,0xb,0x2,0xf,0x8,0x1,
0xd,0x1,0x6,0xa,0x4,0xd,0x9,0x0,
0x8,0x6,0xf,0x9,0x3,0x8,0x0,0x7,
0xb,0x4,0x1,0xf,0x2,0xe,0xc,0x3,
0x5,0xb,0xa,0x5,0xe,0x2,0x7,0xc
},
{
0x7,0xd,0xd,0x8,0xe,0xb,0x3,0x5,
0x0,0x6,0x6,0xf,0x9,0x0,0xa,0x3,
0x1,0x4,0x2,0x7,0x8,0x2,0x5,0xc,
0xb,0x1,0xc,0xa,0x4,0xe,0xf,0x9,
0xa,0x3,0x6,0xf,0x9,0x0,0x0,0x6,
0xc,0xa,0xb,0xa,0x7,0xd,0xd,0x8,
0xf,0x9,0x1,0x4,0x3,0x5,0xe,0xb,
0x5,0xc,0x2,0x7,0x8,0x2,0x4,0xe
},
{
0x2,0xe,0xc,0xb,0x4,0x2,0x1,0xc,
0x7,0x4,0xa,0x7,0xb,0xd,0x6,0x1,
0x8,0x5,0x5,0x0,0x3,0xf,0xf,0xa,
0xd,0x3,0x0,0x9,0xe,0x8,0x9,0x6,
0x4,0xb,0x2,0x8,0x1,0xc,0xb,0x7,
0xa,0x1,0xd,0xe,0x7,0x2,0x8,0xd,
0xf,0x6,0x9,0xf,0xc,0x0,0x5,0x9,
0x6,0xa,0x3,0x4,0x0,0x5,0xe,0x3
},
{
0xc,0xa,0x1,0xf,0xa,0x4,0xf,0x2,
0x9,0x7,0x2,0xc,0x6,0x9,0x8,0x5,
0x0,0x6,0xd,0x1,0x3,0xd,0x4,0xe,
0xe,0x0,0x7,0xb,0x5,0x3,0xb,0x8,
0x9,0x4,0xe,0x3,0xf,0x2,0x5,0xc,
0x2,0x9,0x8,0x5,0xc,0xf,0x3,0xa,
0x7,0xb,0x0,0xe,0x4,0x1,0xa,0x7,
0x1,0x6,0xd,0x0,0xb,0x8,0x6,0xd
},
{
0x4,0xd,0xb,0x0,0x2,0xb,0xe,0x7,
0xf,0x4,0x0,0x9,0x8,0x1,0xd,0xa,
0x3,0xe,0xc,0x3,0x9,0x5,0x7,0xc,
0x5,0x2,0xa,0xf,0x6,0x8,0x1,0x6,
0x1,0x6,0x4,0xb,0xb,0xd,0xd,0x8,
0xc,0x1,0x3,0x4,0x7,0xa,0xe,0x7,
0xa,0x9,0xf,0x5,0x6,0x0,0x8,0xf,
0x0,0xe,0x5,0x2,0x9,0x3,0x2,0xc
},
{
0xd,0x1,0x2,0xf,0x8,0xd,0x4,0x8,
0x6,0xa,0xf,0x3,0xb,0x7,0x1,0x4,
0xa,0xc,0x9,0x5,0x3,0x6,0xe,0xb,
0x5,0x0,0x0,0xe,0xc,0x9,0x7,0x2,
0x7,0x2,0xb,0x1,0x4,0xe,0x1,0x7,
0x9,0x4,0xc,0xa,0xe,0x8,0x2,0xd,
0x0,0xf,0x6,0xc,0xa,0x9,0xd,0x0,
0xf,0x3,0x3,0x5,0x5,0x6,0x8,0xb
}
};
//************************************************************
//****32位right换位表***************************************
static U08 wz_pc3[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
} ;
//**************************************************************
//****最后一次换位表**********************************
static U08 wz_pc4[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
};
//************************************************************
U32 g_outkey[16][2] = {0}; //输出的key (16组48bits)
U32 g_bufkey[2] = {0};
void des(U08 *data, U08 *key);
void handle_data(U32 *left);
void makedata(U32 *left, U32 *right, U32 number);
void makefirstkey(U32 *keyP);
void makekey(U32 *keyleft, U32 *keyright, U32 number); /*输入密钥的地址,一个32位的*/
void main()
{
int i;
U08 data[8]={'g','n','u','e','m','a','c','s'};
U08 key[8]={'s','t','a','l','l','m','a','n'};
// U08 data[8]={0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88}; //数据data[8]
// U08 key[8] ={0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80}; //密钥Key[8]
printf("\n/*******64bit data******/\n");
for(i=0;i<8;++i)
{
printf("0x%02x ",data[i]);
}
printf("\n/*******64bit key******/\n");
for(i=0;i<8;++i)
{
printf("0x%02x ",key[i]);
}
des(data,key);
printf("\n/*******64bit endata******/\n");
for(i=0;i<8;i++)
{
printf("0x%02x ",data[i]);
}
printf("\n");
}
void des(U08 *data ,U08 *key)
{
makefirstkey((U32 *)key); //产生密钥
handle_data((U32 *)data); //加密数据
}
void makefirstkey(U32 *keyP)
{
int j;
U32 *Pkey;
U32 *Pbufkey;
Pbufkey = (U32*)g_bufkey;
Pkey = (U32*)keyP;
// for(j=0;j<2;++j)
// {
// printf("Pbufkey[%d] = 0x%08x\n",j,Pbufkey[j]);
// }
//
// for(j=0;j<2;++j)
// {
// printf(" Pkey[%d] = 0x%08x\n",j,Pkey[j]);
// }
for(j = 0 ;j < 28; j++) //初始置换密钥
{
//*********实现了查表移位操作**************************************************************
if(wz_keyleft[j] > 32) //置换表中的数字大于32,则取Pkey[1]
{
if(Pkey[1]&wz_pc2[wz_keyleft[j]-1]) //wz_pc2[]取得wz_keyleft[j]这一位的值
{
Pbufkey[0] |= wz_pc2[j]; //例如:j=0时将第57位移到第1位
}
}
else
{
if(Pkey[0]&wz_pc2[wz_keyleft[j]-1])
{
Pbufkey[0] |= wz_pc2[j];
}
}
//*****************************************************************************************
if(wz_keyright[j] > 32)
{
if(Pkey[1]&wz_pc2[wz_keyright[j]-1])
{
Pbufkey[1] |= wz_pc2[j];
}
}
else
{
if(Pkey[0]&wz_pc2[wz_keyright[j]-1])
{
Pbufkey[1] |= wz_pc2[j];
}
}
} //Pbufkey[0,1] 就是初始置换后的密钥
// for(j=0;j<2;++j)
// {
// printf("Pbufkey[%d] = 0x%08X\n",j,Pbufkey[j]);
// }
for(j=0; j<16; j++)
{
makekey(&Pbufkey[0], &Pbufkey[1], (U32)j);
// for(int i=0;i<2;++i)
// {
// printf("g_outkey[%d][%d] = 0x%08X\n",j,i,g_outkey[j][i]);
// }
}
}
void makekey(U32 *keyleft, U32 *keyright, U32 number) /*输入密钥的地址,一个32位的*/
{
int j;
U32 tmpkey[2] ={0};
U32 *Ptmpkey = (U32*)tmpkey; //用来存放最高一位或两位
U32 *Poutkey = (U32*)&g_outkey[number];
//************密钥移位操作********************************************
*Ptmpkey = *keyleft&wz_leftandtab[wz_lefttable[number]]; /*要最高的一位或两位*/
Ptmpkey[1] = *keyright&wz_leftandtab[wz_lefttable[number]];
if(wz_lefttable[number] == 1) //循环左移1位28bit的数据即是将最高位移到最后一位,其他左移一位
{
*Ptmpkey >>= 27; //移到最后一位
Ptmpkey[1] >>= 27;
}
else
{
*Ptmpkey >>= 26; //移到最后两位
Ptmpkey[1] >>= 26;
}
// for(j=0;j<2;++j)
// {
// printf("Ptmpkey[%d] = 0x%08x\n",j,Ptmpkey[j]);
// }
Ptmpkey[0] &= 0xfffffff0; //取U32中前28bits有效位
Ptmpkey[1] &= 0xfffffff0;
/*得到高位的值*/
*keyleft <<= wz_lefttable[number];
*keyright <<= wz_lefttable[number];
// printf(" keyleft = 0x%08x\n",*keyleft);
// printf("keyright = 0x%08x\n",*keyright);
*keyleft |= Ptmpkey[0] ; //加上最后一位
*keyright |= Ptmpkey[1] ;
// printf(" keyleft = 0x%08x\n",*keyleft);
// printf("keyright = 0x%08x\n",*keyright);
//************密钥移位操作********************************************
Ptmpkey[0] = 0; //将Ptmpkey[0,1]置为0
Ptmpkey[1] = 0;
// printf("keyright = 0x%08x\n",*keyright);
/*从56位中选出48位*/
for(j = 0; j < 48; j++)
{
if(j < 24)
{
if(*keyleft&wz_pc2[wz_keychoose[j]-1])
{
Poutkey[0] |= wz_pc2[j];
}
}
else /*j>=24*/
{
if(*keyright&wz_pc2[(wz_keychoose[j]-28-1)]) //56bits中后28bits ???
{
Poutkey[1] |= wz_pc2[j-24]; //从wz_pc2[0]开始
}
}
}
}
void handle_data(U32 *left)
{
int number = 0 ,j = 0;
U32 *right = &left[1];
U32 tmp = 0;
U32 tmpbuf[2] = {0};
// printf(" left = 0x%08x\n",*left);
// printf("right = 0x%08x\n",*right);
//**************64bits data初始换位**********************************************
for(j = 0; j < 64; j++)
{
if(j < 32)
{
if(wz_pc1[j] > 32) //属于right
{
if(*right&wz_pc2[wz_pc1[j]-1])
{
tmpbuf[0] |= wz_pc2[j];
}
}
else //属于left
{
if(*left&wz_pc2[wz_pc1[j]-1])
{
tmpbuf[0] |= wz_pc2[j];
}
}
}
else
{
if(wz_pc1[j] > 32) /*属于right*/
{
if(*right&wz_pc2[wz_pc1[j]-1])
{
tmpbuf[1] |= wz_pc2[j];
}
}
else
{
if(*left&wz_pc2[wz_pc1[j]-1] )
{
tmpbuf[1] |= wz_pc2[j] ;
}
}
}
}
*left = tmpbuf[0];
*right = tmpbuf[1];
// printf(" left = 0x%08x\n",*left);
// printf("right = 0x%08x\n",*right);
//********************************************************************************
tmpbuf[0] = 0 ;
tmpbuf[1] = 0 ;
//加密
for(number = 0; number < 16; number++)
{
makedata(left, right, (U32)number);
}
//解密
// for(number = 15; number >= 0; number--)
// {
// makedata( left , right ,(U32)number);
// }
//交换回来 /*最后一轮操作不交换左右值*/
tmp = *left;
*left = *right;
*right = tmp;
//******************数据整理 最后一次调整wz_pc4[64]*************************************
for(j = 0; j < 64; j++)
{
if(j < 32)
{
if(wz_pc4[j] > 32)/*属于right*/
{
if (*right&wz_pc2[wz_pc4[j]-1])
{
tmpbuf[0] |= wz_pc2[j];
}
}
else
{
if(*left&wz_pc2[wz_pc4[j]-1])
{
tmpbuf[0] |= wz_pc2[j];
}
}
}
else
{
if(wz_pc4[j] > 32)/*属于right*/
{
if(*right&wz_pc2[wz_pc4[j]-1])
{
tmpbuf[1] |= wz_pc2[j];
}
}
else
{
if(*left&wz_pc2[wz_pc4[j]-1])
{
tmpbuf[1] |= wz_pc2[j];
}
}
}
}
*left = tmpbuf[0];
*right = tmpbuf[1];
printf("\n0x%08X\n",*left);
printf("0x%08X\n",*right);
//*****************************************************************************************
}
void makedata(U32 *left ,U32 *right ,U32 number)
{
int j;
U32 oldright = *right;
U08 rexpbuf[8] = {0};
U32 datatmp = 0;
U32 exp[2] = {0};
//****************** right由32位扩展成48位*************************************************
for(j = 0; j < 48; j++)
{
/*两个32位,每个存放24位*/
if(j < 24)
{
if(*right&wz_pc2[exptab3[j]-1])
{
exp[0] |= wz_pc2[j];
}
}
else
{
if(*right&wz_pc2[exptab3[j]-1])
{
exp[1] |= wz_pc2[j-24];
}
}
}
//****************************************************************************************
//********扩展后的48位right与第i次迭代生成的48位加密密钥进行按位异或操作******************
for (j = 0; j < 2; j++)
{
exp[j] ^= g_outkey[number][j];
}
//*****************************************************************************************
//********把48位的right值转换成32位的right值***********************************************
exp[1] >>= 8; //前24bits为有效值右移8位
rexpbuf[7] = (U08)(exp[1]&0x0000003fL); //取出最后6位
exp[1] >>= 6; //继续右移6位,然后取出
rexpbuf[6] = (U08)(exp[1]&0x0000003fL);
exp[1] >>= 6;
rexpbuf[5] = (U08)(exp[1]&0x0000003fL);
exp[1] >>= 6;
rexpbuf[4] = (U08)(exp[1]&0x0000003fL);
exp[0] >>= 8;
rexpbuf[3] = (U08)(exp[0]&0x0000003fL);
exp[0] >>= 6;
rexpbuf[2] = (U08)(exp[0]&0x0000003fL);
exp[0] >>= 6;
rexpbuf[1] = (U08)(exp[0]&0x0000003fL);
exp[0] >>= 6;
rexpbuf[0] = (U08)(exp[0]&0x0000003fL);
exp[0] = 0;
exp[1] = 0;
//rexpbuf[0]查表1,rexpbuf[1]查表2,...
*right = 0;
for(j = 0; j < 7; j++)
{
*right |= SP[j][rexpbuf[j]-1]; //( rexpbuf[j]-1 )???
*right<<= 4;
}
*right|= SP[j][rexpbuf[j]-1];
//*************************************************************************************************
//************又要换位了****************************************************************************
datatmp = 0;
for(j = 0; j < 32; j++)
{
if(*right&wz_pc2[wz_pc3[j]-1])
{
datatmp |= wz_pc2[j];
}
}
*right = datatmp;
//****************************************************************************************************
/*一轮结束收尾操作*/
*right ^= *left;
*left = oldright;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -