📄 des.cpp.txt
字号:
// des.cpp : Defines the entry point for the console application.
//
// des.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <memory.h>
#include <windows.h>
#include <iostream.h>
#include <malloc.h>
#include "fstream.h"
char* pstroutput=(char *)malloc(1024*1024);//记录所有的字符输出
char* pstroutput0=pstroutput;//记下初始位置。
//扩展选排阵
char ei[] =
{
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
};
//密钥选排阵 64bits->56bits
char pc1[] = /* Permuted choice table (key) */
{
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
};
//密钥生成的循环左移表
char totRot[] = /* Number left rotations of pc1 */
{
1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
}; /* totRot[] */
//压缩选排阵56bits->48bits
char pc2[] = /* Permuted choice key (table) */
{
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
}; /* pc2[] */
/* 8 6-bit subkeys for each of 16 rounds, initialized by SetKey() */
unsigned char kn[16][8];
/* bit 0 is left-most in byte */
int byteBit[] =
{
0200, 0100, 040, 020, 010, 04, 02, 01 //128,64,32,16,8,4,2,1以8进制表示的。
}; /* byteBit[] */
//用于手工运算验证可以不实现
void SetKey(int doEncrypt,unsigned char *key)
{
char pc1m[56]; /* Place to modify pc1 into */
char pcr[56]; /* Place to rotate pc1 into */
register int i ,j , k;
int m;
if(doEncrypt) pstroutput+=sprintf(pstroutput,"用户输入的64位密钥如下:\n二进制 十六进制\n");
if (doEncrypt)
{
pstroutput+=sprintf(pstroutput,"\n");
for (j = 0; j < 8; j++) pstroutput+=sprintf(pstroutput,"%d\t",j);
}
if (doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
if (doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
for (j = 0; j < 64; j++)
{
k = j; /* Integer bit location 将起点定到从0起*/
m = k & 07; /* find bit 归到一个字节里的哪一位(000-111 */
if(doEncrypt) pstroutput+=sprintf(pstroutput,"%d\t", (key[k >> 3] & byteBit[m]) ? 1 : 0);
//k >> 3找到所第几位所属字节,再求于字节中第几位
if ((j+1)%8==0 && doEncrypt) pstroutput+=sprintf(pstroutput," 0X%0X\n",key[k >> 3]);
} /* end of for j */
if (doEncrypt)
{
pstroutput+=sprintf(pstroutput,"\n");
for (j = 56; j < 64; j++) pstroutput+=sprintf(pstroutput,"%d\t",j);
}
if (doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
/* Clear key schedule */
if(doEncrypt)
{
pstroutput+=sprintf(pstroutput,"/******************步骤1:子密钥处理开始**************************/\n");
pstroutput+=sprintf(pstroutput,"步骤1-1:去奇偶校验位(每个字节最左边的位),而后重排56位:\n");
}
for (i = 0; i < 16; i++)
{
for (j = 0; j < 8; j++)
kn[i][j] = 0;//密钥清零
} /* end of for i */
if (doEncrypt) pstroutput+=sprintf(pstroutput,"L 28位:\n");
for (j = 0; j < 28; j++)
{
if (doEncrypt)
{
pstroutput+=sprintf(pstroutput,"%02d ", pc1[j]);
if ((j+1)%7==0 && doEncrypt) pstroutput+=sprintf(pstroutput,"| ");
//if ((j+1)%24==0 && doEncrypt)pstroutput+=sprintf(pstroutput,"\n");
}
}
if (doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
for (j = 0; j < 56; j++)
{//pc1[0]=57,k=56,m=0x00,56>>3=0x7在第7字节,第0位,
//每个字节的起始编号位不再是校验位而是其右1位,56个位都左移1位即-1
//校验位:0,8,16,8k位
k = pc1[j]; /* Integer bit location 每字节都去了1校验位,*/
m = k & 07; /* find bit 归到一个字节里的哪一位(000-111 */
if(doEncrypt) pstroutput+=sprintf(pstroutput,"%d ", (key[k >> 3] & byteBit[m]) ? 1 : 0);
//k >> 3找到所第几位所属字节,再求于字节中第几位
if (j==27 && doEncrypt)
{
pstroutput+=sprintf(pstroutput,"\nR 28位:\n");
for (int tempj = 28; tempj < 56; tempj++)
{
if (doEncrypt)
{
pstroutput+=sprintf(pstroutput,"%02d ", pc1[tempj]);
if ((tempj+1)%7==0 && doEncrypt) pstroutput+=sprintf(pstroutput,"| ");
//if ((j+1)%24==0 && doEncrypt)pstroutput+=sprintf(pstroutput,"\n");
}
}
//if (doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
}
if ((j+1)%7==0 && doEncrypt) pstroutput+=sprintf(pstroutput," ");
if ((j+1)%28==0 && doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
} /* end of for j */
/* Convert pc1 to bits of key */
for (j = 0; j < 56; j++)
{
k = pc1[j]; /* Integer bit location 将起点定到从0起*/
m = k & 07; /* find bit 归到一个字节里的哪一位(000-111 */
pc1m[j] = (key[k >> 3] & byteBit[m]) ? 1 : 0;//k >> 3找到所第几位所属字节,再求于字节中第几位
} /* end of for j */
/* Key chunk for each iteration */
for (i = 0; i < 16; i++)
{
/* rotate pc1 the right amount */
for (j = 0; j < 56; j++)
{
//循环左移:即用右边(编号大)的位去写左边的(编号小)的位
k = j + totRot[i];/*static const char totRot[] = 1, 2(1+1), 4(1+1+2+2,教材上前面左移几项位数之和), 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28};*/
pcr[j] = pc1m[(k < (j < 28 ? 28 : 56)) ? k : k - 28];//(j < 28 ? 28 : 56):取28则左半,取56右半,k - 28表示循环移位的
if( doEncrypt)
{
if (j==0)
{
if(i==0) pstroutput+=sprintf(pstroutput,"/******************步骤1-2:生成子密钥**************************/\n");
if(i==0)pstroutput+=sprintf(pstroutput,"步骤1-2-%d-1:第%d轮循环左移,左移%d位后:\n",i,i,totRot[i]);
else pstroutput+=sprintf(pstroutput,"步骤1-2-%d-1:第%d轮循环左移累计%d位,在前基础上再左移%d位后:\n",i,i,totRot[i],totRot[i]-totRot[i-1]);
pstroutput+=sprintf(pstroutput,"左28位:\n");
}
pstroutput+=sprintf(pstroutput,"%d", pc1m[(k < (j < 28 ? 28 : 56)) ? k : k - 28]); //(j < 28 ? 28 : 56):取28则左半,取56右半,k - 28表示循环移位的
if (j==27) pstroutput+=sprintf(pstroutput,"\n右28位:");
if ((j+1)%7==0) pstroutput+=sprintf(pstroutput," ");
if ((j+1)%28==0 && doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
}
} /* end of for j */
if( doEncrypt)pstroutput+=sprintf(pstroutput,"步骤1-2-%d-2:第%d轮循环左移,累计左移%d位后左右合并得:\n",i,i,totRot[i]);
if( doEncrypt)for (j = 0; j < 56; j++)
{
pstroutput+=sprintf(pstroutput,"%d",(j%7+1));
if ((j+1)%7==0) pstroutput+=sprintf(pstroutput," ");
}
if( doEncrypt)pstroutput+=sprintf(pstroutput,"\n");
for (j = 0; j < 56; j++)
{
//循环左移:即用右边(编号大)的位去写左边的(编号小)的位
k = j + totRot[i];/*static const char totRot[] = 1, 2(1+1), 4(1+1+2+2,教材上前面左移几项位数之和), 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28};*/
pcr[j] = pc1m[(k < (j < 28 ? 28 : 56)) ? k : k - 28];//(j < 28 ? 28 : 56):取28则左半,取56右半,k - 28表示循环移位的
if( doEncrypt)
{
pstroutput+=sprintf(pstroutput,"%d", pc1m[(k < (j < 28 ? 28 : 56)) ? k : k - 28]); //(j < 28 ? 28 : 56):取28则左半,取56右半,k - 28表示循环移位的
if ((j+1)%7==0) pstroutput+=sprintf(pstroutput," ");
if ((j+1)%56==0 && doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
}
} /* end of for j */
/* Rotate left and right halves independently */
if (doEncrypt)pstroutput+=sprintf(pstroutput,"步骤1-2-%d-3:照以下数组进行选位并排序:\n",i);
for (j=0; j<48; j++)//
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -