当前位置:首页 » 课程大全 » des加密算法课程设计

des加密算法课程设计

发布时间: 2021-02-23 03:12:45

『壹』 求教des算法的详细过程

图为最详细的流程

下附上完整C程序,我自己做的,你看看。

#include"stdio.h"

#include"memory.h"

#include"time.h"

#include"stdlib.h"

#definePLAIN_FILE_OPEN_ERROR-1

#defineKEY_FILE_OPEN_ERROR-2

#defineCIPHER_FILE_OPEN_ERROR-3

#defineOK1

typedefcharElemType;

/*初始置换表IP*/

intIP_Table[64]={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,

56,48,40,32,24,16,8,0,

58,50,42,34,26,18,10,2,

60,52,44,36,28,20,12,4,

62,54,46,38,30,22,14,6};

/*逆初始置换表IP^-1*/

intIP_1_Table[64]={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,

32,0,40,8,48,16,56,24};

/*扩充置换表E*/

intE_Table[48]={31,0,1,2,3,4,

3,4,5,6,7,8,

7,8,9,10,11,12,

11,12,13,14,15,16,

15,16,17,18,19,20,

19,20,21,22,23,24,

23,24,25,26,27,28,

27,28,29,30,31,0};

/*置换函数P*/

intP_Table[32]={15,6,19,20,28,11,27,16,

0,14,22,25,4,17,30,9,

1,7,23,13,31,26,2,8,

18,12,29,5,21,10,3,24};

/*S盒*/

intS[8][4][16]=

/*S1*/

{{{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}},

/*S2*/

{{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}},

/*S3*/

{{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}},

/*S4*/

{{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}},

/*S5*/

{{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}},

/*S6*/

{{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}},

/*S7*/

{{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}},

/*S8*/

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

/*置换选择1*/

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

/*置换选择2*/

intPC_2[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,46,43,48,38,55,

33,52,45,41,49,35,28,31};

/*对左移次数的规定*/

intMOVE_TIMES[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

intByteToBit(ElemTypech,ElemTypebit[8]);

intBitToByte(ElemTypebit[8],ElemType*ch);

intChar8ToBit64(ElemTypech[8],ElemTypebit[64]);

intBit64ToChar8(ElemTypebit[64],ElemTypech[8]);

intDES_MakeSubKeys(ElemTypekey[64],ElemTypesubKeys[16][48]);

intDES_PC1_Transform(ElemTypekey[64],ElemTypetempbts[56]);

intDES_PC2_Transform(ElemTypekey[56],ElemTypetempbts[48]);

intDES_ROL(ElemTypedata[56],inttime);

intDES_IP_Transform(ElemTypedata[64]);

intDES_IP_1_Transform(ElemTypedata[64]);

intDES_E_Transform(ElemTypedata[48]);

intDES_P_Transform(ElemTypedata[32]);

intDES_SBOX(ElemTypedata[48]);

intDES_XOR(ElemTypeR[48],ElemTypeL[48],intcount);

intDES_Swap(ElemTypeleft[32],ElemTyperight[32]);

intDES_EncryptBlock(ElemTypeplainBlock[8],ElemTypesubKeys[16][48],ElemTypecipherBlock[8]);

intDES_DecryptBlock(ElemTypecipherBlock[8],ElemTypesubKeys[16][48],ElemTypeplainBlock[8]);

intDES_Encrypt(char*plainFile,char*keyStr,char*cipherFile);

intDES_Decrypt(char*cipherFile,char*keyStr,char*plainFile);

/*字节转换成二进制*/

intByteToBit(ElemTypech,ElemTypebit[8]){

intcnt;

for(cnt=0;cnt<8;cnt++){

*(bit+cnt)=(ch>>cnt)&1;

}

return0;

}

/*二进制转换成字节*/

intBitToByte(ElemTypebit[8],ElemType*ch){

intcnt;

for(cnt=0;cnt<8;cnt++){

*ch|=*(bit+cnt)<<cnt;

}

return0;

}

/*将长度为8的字符串转为二进制位串*/

intChar8ToBit64(ElemTypech[8],ElemTypebit[64]){

intcnt;

for(cnt=0;cnt<8;cnt++){

ByteToBit(*(ch+cnt),bit+(cnt<<3));

}

return0;

}

/*将二进制位串转为长度为8的字符串*/

intBit64ToChar8(ElemTypebit[64],ElemTypech[8]){

intcnt;

memset(ch,0,8);

for(cnt=0;cnt<8;cnt++){

BitToByte(bit+(cnt<<3),ch+cnt);

}

return0;

}

/*生成子密钥*/

intDES_MakeSubKeys(ElemTypekey[64],ElemTypesubKeys[16][48]){

ElemTypetemp[56];

intcnt;

DES_PC1_Transform(key,temp);/*PC1置换*/

for(cnt=0;cnt<16;cnt++){/*16轮跌代,产生16个子密钥*/

DES_ROL(temp,MOVE_TIMES[cnt]);/*循环左移*/

DES_PC2_Transform(temp,subKeys[cnt]);/*PC2置换,产生子密钥*/

}

return0;

}

/*密钥置换1*/

intDES_PC1_Transform(ElemTypekey[64],ElemTypetempbts[56]){

intcnt;

for(cnt=0;cnt<56;cnt++){

tempbts[cnt]=key[PC_1[cnt]];

}

return0;

}

/*密钥置换2*/

intDES_PC2_Transform(ElemTypekey[56],ElemTypetempbts[48]){

intcnt;

for(cnt=0;cnt<48;cnt++){

tempbts[cnt]=key[PC_2[cnt]];

}

return0;

}

/*循环左移*/

intDES_ROL(ElemTypedata[56],inttime){

ElemTypetemp[56];

/*保存将要循环移动到右边的位*/

memcpy(temp,data,time);

memcpy(temp+time,data+28,time);

/*前28位移动*/

memcpy(data,data+time,28-time);

memcpy(data+28-time,temp,time);

/*后28位移动*/

memcpy(data+28,data+28+time,28-time);

memcpy(data+56-time,temp+time,time);

return0;

}

/*IP置换*/

intDES_IP_Transform(ElemTypedata[64]){

intcnt;

ElemTypetemp[64];

for(cnt=0;cnt<64;cnt++){

temp[cnt]=data[IP_Table[cnt]];

}

memcpy(data,temp,64);

return0;

}

/*IP逆置换*/

intDES_IP_1_Transform(ElemTypedata[64]){

intcnt;

ElemTypetemp[64];

for(cnt=0;cnt<64;cnt++){

temp[cnt]=data[IP_1_Table[cnt]];

}

memcpy(data,temp,64);

return0;

}

/*扩展置换*/

intDES_E_Transform(ElemTypedata[48]){

intcnt;

ElemTypetemp[48];

for(cnt=0;cnt<48;cnt++){

temp[cnt]=data[E_Table[cnt]];

}

memcpy(data,temp,48);

return0;

}

/*P置换*/

intDES_P_Transform(ElemTypedata[32]){

intcnt;

ElemTypetemp[32];

for(cnt=0;cnt<32;cnt++){

temp[cnt]=data[P_Table[cnt]];

}

memcpy(data,temp,32);

return0;

}

/*异或*/

intDES_XOR(ElemTypeR[48],ElemTypeL[48],intcount){

intcnt;

for(cnt=0;cnt<count;cnt++){

R[cnt]^=L[cnt];

}

return0;

}

/*S盒置换*/

intDES_SBOX(ElemTypedata[48]){

intcnt;

intline,row,output;

intcur1,cur2;

for(cnt=0;cnt<8;cnt++){

cur1=cnt*6;

cur2=cnt<<2;

/*计算在S盒中的行与列*/

line=(data[cur1]<<1)+data[cur1+5];

row=(data[cur1+1]<<3)+(data[cur1+2]<<2)

+(data[cur1+3]<<1)+data[cur1+4];

output=S[cnt][line][row];

/*化为2进制*/

data[cur2]=(output&0X08)>>3;

data[cur2+1]=(output&0X04)>>2;

data[cur2+2]=(output&0X02)>>1;

data[cur2+3]=output&0x01;

}

return0;

}

/*交换*/

intDES_Swap(ElemTypeleft[32],ElemTyperight[32]){

ElemTypetemp[32];

memcpy(temp,left,32);

memcpy(left,right,32);

memcpy(right,temp,32);

return0;

}

/*加密单个分组*/

intDES_EncryptBlock(ElemTypeplainBlock[8],ElemTypesubKeys[16][48],ElemTypecipherBlock[8]){

ElemTypeplainBits[64];

ElemTypeRight[48];

intcnt;

Char8ToBit64(plainBlock,plainBits);

/*初始置换(IP置换)*/

DES_IP_Transform(plainBits);

/*16轮迭代*/

for(cnt=0;cnt<16;cnt++){

memcpy(Right,plainBits+32,32);

/*将右半部分进行扩展置换,从32位扩展到48位*/

DES_E_Transform(Right);

/*将右半部分与子密钥进行异或操作*/

DES_XOR(Right,subKeys[cnt],48);

/*异或结果进入S盒,输出32位结果*/

DES_SBOX(Right);

/*P置换*/

DES_P_Transform(Right);

/*将明文左半部分与右半部分进行异或*/

DES_XOR(plainBits,Right,32);

if(cnt!=15){

/*最终完成左右部的交换*/

DES_Swap(plainBits,plainBits+32);

}

}

/*逆初始置换(IP^1置换)*/

DES_IP_1_Transform(plainBits);

Bit64ToChar8(plainBits,cipherBlock);

return0;

}

/*解密单个分组*/

intDES_DecryptBlock(ElemTypecipherBlock[8],ElemTypesubKeys[16][48],ElemTypeplainBlock[8]){

ElemTypecipherBits[64];

ElemTypeRight[48];

intcnt;

Char8ToBit64(cipherBlock,cipherBits);

/*初始置换(IP置换)*/

DES_IP_Transform(cipherBits);

/*16轮迭代*/

for(cnt=15;cnt>=0;cnt--){

memcpy(Right,cipherBits+32,32);

/*将右半部分进行扩展置换,从32位扩展到48位*/

DES_E_Transform(Right);

/*将右半部分与子密钥进行异或操作*/

DES_XOR(Right,subKeys[cnt],48);

/*异或结果进入S盒,输出32位结果*/

DES_SBOX(Right);

/*P置换*/

DES_P_Transform(Right);

/*将明文左半部分与右半部分进行异或*/

DES_XOR(cipherBits,Right,32);

if(cnt!=0){

/*最终完成左右部的交换*/

DES_Swap(cipherBits,cipherBits+32);

}

}

/*逆初始置换(IP^1置换)*/

DES_IP_1_Transform(cipherBits);

Bit64ToChar8(cipherBits,plainBlock);

return0;

}

/*加密文件*/

intDES_Encrypt(char*plainFile,char*keyStr,char*cipherFile){

FILE*plain,*cipher;

intcount;

ElemTypeplainBlock[8],cipherBlock[8],keyBlock[8];

ElemTypebKey[64];

ElemTypesubKeys[16][48];

if((plain=fopen(plainFile,"rb"))==NULL){

returnPLAIN_FILE_OPEN_ERROR;

}

if((cipher=fopen(cipherFile,"wb"))==NULL){

returnCIPHER_FILE_OPEN_ERROR;

}

/*设置密钥*/

memcpy(keyBlock,keyStr,8);

/*将密钥转换为二进制流*/

Char8ToBit64(keyBlock,bKey);

/*生成子密钥*/

DES_MakeSubKeys(bKey,subKeys);

while(!feof(plain)){

/*每次读8个字节,并返回成功读取的字节数*/

if((count=fread(plainBlock,sizeof(char),8,plain))==8){

DES_EncryptBlock(plainBlock,subKeys,cipherBlock);

fwrite(cipherBlock,sizeof(char),8,cipher);

}

}

if(count){

/*填充*/

memset(plainBlock+count,'',7-count);

/*最后一个字符保存包括最后一个字符在内的所填充的字符数量*/

plainBlock[7]=8-count;

DES_EncryptBlock(plainBlock,subKeys,cipherBlock);

fwrite(cipherBlock,sizeof(char),8,cipher);

}

fclose(plain);

fclose(cipher);

returnOK;

}

/*解密文件*/

intDES_Decrypt(char*cipherFile,char*keyStr,char*plainFile){

FILE*plain,*cipher;

intcount,times=0;

longfileLen;

ElemTypeplainBlock[8],cipherBlock[8],keyBlock[8];

ElemTypebKey[64];

ElemTypesubKeys[16][48];

if((cipher=fopen(cipherFile,"rb"))==NULL){

returnCIPHER_FILE_OPEN_ERROR;

}

if((plain=fopen(plainFile,"wb"))==NULL){

returnPLAIN_FILE_OPEN_ERROR;

}

/*设置密钥*/

memcpy(keyBlock,keyStr,8);

/*将密钥转换为二进制流*/

Char8ToBit64(keyBlock,bKey);

/*生成子密钥*/

DES_MakeSubKeys(bKey,subKeys);

/*取文件长度*/

fseek(cipher,0,SEEK_END);/*将文件指针置尾*/

fileLen=ftell(cipher);/*取文件指针当前位置*/

rewind(cipher);/*将文件指针重指向文件头*/

while(1){

/*密文的字节数一定是8的整数倍*/

fread(cipherBlock,sizeof(char),8,cipher);

DES_DecryptBlock(cipherBlock,subKeys,plainBlock);

times+=8;

if(times<fileLen){

fwrite(plainBlock,sizeof(char),8,plain);

}

else{

break;

}

}

/*判断末尾是否被填充*/

if(plainBlock[7]<8){

for(count=8-plainBlock[7];count<7;count++){

if(plainBlock[count]!=''){

break;

}

}

}

if(count==7){/*有填充*/

fwrite(plainBlock,sizeof(char),8-plainBlock[7],plain);

}

else{/*无填充*/

fwrite(plainBlock,sizeof(char),8,plain);

}

fclose(plain);

fclose(cipher);

returnOK;

}

intmain()

{

clock_ta,b;

a=clock();

DES_Encrypt("1.txt","key.txt","2.txt");

b=clock();

printf("加密消耗%d毫秒 ",b-a);

system("pause");

a=clock();

DES_Decrypt("2.txt","key.txt","3.txt");

b=clock();

printf("解密消耗%d毫秒 ",b-a);

getchar();

return0;

}

『贰』 DES算法加密的算法步骤是

#define READFILESIZE 512
步骤:
1.从文件中读取READFILESIZE个字节的数据
2.,如果从文件中读出的数据少于READFILESIZE个,以0补足专,然后根据用户指定的属类型对这READFILESIZE个字节的数据进行操作.
3.判断文件是否结束,没有则执行步骤1
4.把加密后的文件实际长度添加到密文的末尾
5.结束
采用一次只从文件读取READFILESIZE个字节是在为了防止由于需要加密或解密的文件太大导致内存不够的情况出现。

『叁』 高分求高手指导密码学课程设计 使用VC++实现DES加密/解密算法的软件系统

找个DES源码,自己加入MFC的界面就可以了

『肆』 DES加密算法的测试数据示例

其实复你只要再写个解密的过程看看制加密完能不能还原回去就好了。。解密过程和加密过程基本一样,就是使用子密钥时的顺序是倒着的。
明文是 testdata,密钥是mydeskey 正确的des加密后二进制密文:
用base64编码形成的密文是:4wynQOzDaiA=
解密后:

『伍』 des加密解密算法的完整程序

到VCKBase上找
http://www.vckbase.com/document/viewdoc/?id=623
http://www.vckbase.com/document/viewdoc/?id=624

『陆』 请问关于DES加密算法,程序实现都可以有哪些不同

1.密钥不同
2.程序算法不同:不是说DES的算法,是指你所写的程序代码去实现DES算法不同,象有些关于循环部分的代码,不同的人可能写的不同,导致程序代码在大量加密时效率不高
暂时只想到这了...

『柒』 基于C语言的DES加密算法的实现 要怎么写啊

首先c语言要熟悉,然后去图书馆借一本加密解密的书,要里面有c语言回des实现代码的(这种书答是有的,我看到过)。论文先对加密解密的历史及发展现状进行介绍,然后着重对des加密的发展历史及原理进行阐述(以上内容要多借几本相关书综合一下用自己的语言表达出来)。然后对des的算法写个程序(可以利用书里面的程序),然后运行结果截几张图下来。最后总结一下,论文就可以了。

『捌』 des算法加密解密的实现

一.加密

DES算法处理的数据对象是一组64比特的明文串。设该明文串为m=m1m2…m64 (mi=0或1)。明文串经过64比特的密钥K来加密,最后生成长度为64比特的密文E。其加密过程图示如下:

DES算法加密过程
对DES算法加密过程图示的说明如下:待加密的64比特明文串m,经过IP置换后,得到的比特串的下标列表如下:

IP 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

该比特串被分为32位的L0和32位的R0两部分。R0子密钥K1(子密钥的生成将在后面讲)经过变换f(R0,K1)(f变换将在下面讲)输出32位的比特串f1,f1与L0做不进位的二进制加法运算。运算规则为:

f1与L0做不进位的二进制加法运算后的结果赋给R1,R0则原封不动的赋给L1。L1与R0又做与以上完全相同的运算,生成L2,R2…… 一共经过16次运算。最后生成R16和L16。其中R16为L15与f(R15,K16)做不进位二进制加法运算的结果,L16是R15的直接赋值。

R16与L16合并成64位的比特串。值得注意的是R16一定要排在L16前面。R16与L16合并后成的比特串,经过置换IP-1后所得比特串的下标列表如下:
IP-1 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

经过置换IP-1后生成的比特串就是密文e.。
下面再讲一下变换f(Ri-1,Ki)。
它的功能是将32比特的输入再转化为32比特的输出。其过程如图所示:

对f变换说明如下:输入Ri-1(32比特)经过变换E后,膨胀为48比特。膨胀后的比特串的下标列表如下:

E: 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

膨胀后的比特串分为8组,每组6比特。各组经过各自的S盒后,又变为4比特(具体过程见后),合并后又成为32比特。该32比特经过P变换后,其下标列表如下:

P: 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

经过P变换后输出的比特串才是32比特的f (Ri-1,Ki)。
下面再讲一下S盒的变换过程。任取一S盒。见图:

在其输入b1,b2,b3,b4,b5,b6中,计算出x=b1*2+b6, y=b5+b4*2+b3*4+b2*8,再从Si表中查出x 行,y 列的值Sxy。将Sxy化为二进制,即得Si盒的输出。(S表如图所示)

至此,DES算法加密原理讲完了。在VC++6.0下的程序源代码为:

for(i=1;i<=64;i++)
m1[i]=m[ip[i-1]];//64位明文串输入,经过IP置换。

下面进行迭代。由于各次迭代的方法相同只是输入输出不同,因此只给出其中一次。以第八次为例://进行第八次迭代。首先进行S盒的运算,输入32位比特串。
for(i=1;i<=48;i++)//经过E变换扩充,由32位变为48位
RE1[i]=R7[E[i-1]];
for(i=1;i<=48;i++)//与K8按位作不进位加法运算
RE1[i]=RE1[i]+K8[i];
for(i=1;i<=48;i++)
{
if(RE1[i]==2)
RE1[i]=0;
}
for(i=1;i<7;i++)//48位分成8组
{
s11[i]=RE1[i];
s21[i]=RE1[i+6];
s31[i]=RE1[i+12];
s41[i]=RE1[i+18];
s51[i]=RE1[i+24];
s61[i]=RE1[i+30];
s71[i]=RE1[i+36];
s81[i]=RE1[i+42];
}//下面经过S盒,得到8个数。S1,s2,s3,s4,s5,s6,s7,s8分别为S表
s[1]=s1[s11[6]+s11[1]*2][s11[5]+s11[4]*2+s11[3]*4+s11[2]*8];
s[2]=s2[s21[6]+s21[1]*2][s21[5]+s21[4]*2+s21[3]*4+s21[2]*8];
s[3]=s3[s31[6]+s31[1]*2][s31[5]+s31[4]*2+s31[3]*4+s31[2]*8];
s[4]=s4[s41[6]+s41[1]*2][s41[5]+s41[4]*2+s41[3]*4+s41[2]*8];
s[5]=s5[s51[6]+s51[1]*2][s51[5]+s51[4]*2+s51[3]*4+s51[2]*8];
s[6]=s6[s61[6]+s61[1]*2][s61[5]+s61[4]*2+s61[3]*4+s61[2]*8];
s[7]=s7[s71[6]+s71[1]*2][s71[5]+s71[4]*2+s71[3]*4+s71[2]*8];
s[8]=s8[s81[6]+s81[1]*2][s81[5]+s81[4]*2+s81[3]*4+s81[2]*8];
for(i=0;i<8;i++)//8个数变换输出二进制
{
for(j=1;j<5;j++)
{
temp[j]=s[i+1]%2;
s[i+1]=s[i+1]/2;
}
for(j=1;j<5;j++)
f[4*i+j]=temp[5-j];
}
for(i=1;i<33;i++)//经过P变换
frk[i]=f[P[i-1]];//S盒运算完成
for(i=1;i<33;i++)//左右交换
L8[i]=R7[i];
for(i=1;i<33;i++)//R8为L7与f(R,K)进行不进位二进制加法运算结果
{
R8[i]=L7[i]+frk[i];
if(R8[i]==2)
R8[i]=0;
}

[ 原创文档 本文适合中级读者 已阅读21783次 ] 文档 代码 工具

DES算法及其在VC++6.0下的实现(下)
作者:航天医学工程研究所四室 朱彦军

在《DES算法及其在VC++6.0下的实现(上)》中主要介绍了DES算法的基本原理,下面让我们继续:

二.子密钥的生成
64比特的密钥生成16个48比特的子密钥。其生成过程见图:

子密钥生成过程具体解释如下:
64比特的密钥K,经过PC-1后,生成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

该比特串分为长度相等的比特串C0和D0。然后C0和D0分别循环左移1位,得到C1和D1。C1和D1合并起来生成C1D1。C1D1经过PC-2变换后即生成48比特的K1。K1的下标列表为:

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

C1、D1分别循环左移LS2位,再合并,经过PC-2,生成子密钥K2……依次类推直至生成子密钥K16。
注意:Lsi (I =1,2,….16)的数值是不同的。具体见下表:

迭代顺序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
左移位数 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1

生成子密钥的VC程序源代码如下:

for(i=1;i<57;i++)//输入64位K,经过PC-1变为56位 k0[i]=k[PC_1[i-1]];

56位的K0,均分为28位的C0,D0。C0,D0生成K1和C1,D1。以下几次迭代方法相同,仅以生成K8为例。 for(i=1;i<27;i++)//循环左移两位
{
C8[i]=C7[i+2];
D8[i]=D7[i+2];
}
C8[27]=C7[1];
D8[27]=D7[1];
C8[28]=C7[2];
D8[28]=D7[2];
for(i=1;i<=28;i++)
{
C[i]=C8[i];
C[i+28]=D8[i];
}
for(i=1;i<=48;i++)
K8[i]=C[PC_2[i-1]];//生成子密钥k8

注意:生成的子密钥不同,所需循环左移的位数也不同。源程序中以生成子密钥 K8为例,所以循环左移了两位。但在编程中,生成不同的子密钥应以Lsi表为准。

三.解密

DES的解密过程和DES的加密过程完全类似,只不过将16圈的子密钥序列K1,K2……K16的顺序倒过来。即第一圈用第16个子密钥K16,第二圈用K15,其余类推。
第一圈:

加密后的结果

L=R15, R=L15⊕f(R15,K16)⊕f(R15,K16)=L15
同理R15=L14⊕f(R14,K15), L15=R14。
同理类推:
得 L=R0, R=L0。
其程序源代码与加密相同。在此就不重写。

四.示例
例如:已知明文m=learning, 密钥 k=computer。
明文m的ASCII二进制表示:

m= 01101100 01100101 01100001 01110010
01101110 01101001 01101110 01100111

密钥k的ASCII二进制表示:

k=01100011 01101111 01101101 01110000
01110101 01110100 01100101 01110010

明文m经过IP置换后,得:

11111111 00001000 11010011 10100110 00000000 11111111 01110001 11011000

等分为左右两段:

L0=11111111 00001000 11010011 10100110 R0=00000000 11111111 01110001 11011000

经过16次迭代后,所得结果为:

L1=00000000 11111111 01110001 11011000 R1=00110101 00110001 00111011 10100101
L2=00110101 00110001 00111011 10100101 R2=00010111 11100010 10111010 10000111
L3=00010111 11100010 10111010 10000111 R3=00111110 10110001 00001011 10000100
L4= R4=
L5= R5=
L6= R6=
L7= R7=
L8= R8=
L9= R9=
L10= R10=
L11= R11=
L12= R12=
L13= R13=
L14= R14=
L15= R15=
L16= R16=

其中,f函数的结果为:

f1= f2=
f3= f4=
f5= f6=
f7= f8=
f9= f10=
f11= f12=
f13= f14=
f15= f16=

16个子密钥为:

K1= K2=
K3= K4=
K5= K6=
K7= K8=
K9= K10=
K11= K12=
K13= K14=
K15= K16=

S盒中,16次运算时,每次的8 个结果为:
第一次:5,11,4,1,0,3,13,9;
第二次:7,13,15,8,12,12,13,1;
第三次:8,0,0,4,8,1,9,12;
第四次:0,7,4,1,7,6,12,4;
第五次:8,1,0,11,5,0,14,14;
第六次:14,12,13,2,7,15,14,10;
第七次:12,15,15,1,9,14,0,4;
第八次:15,8,8,3,2,3,14,5;
第九次:8,14,5,2,1,15,5,12;
第十次:2,8,13,1,9,2,10,2;
第十一次:10,15,8,2,1,12,12,3;
第十二次:5,4,4,0,14,10,7,4;
第十三次:2,13,10,9,2,4,3,13;
第十四次:13,7,14,9,15,0,1,3;
第十五次:3,1,15,5,11,9,11,4;
第十六次:12,3,4,6,9,3,3,0;

子密钥生成过程中,生成的数值为:

C0=0000000011111111111111111011 D0=1000001101110110000001101000
C1=0000000111111111111111110110 D1=0000011011101100000011010001
C2=0000001111111111111111101100 D2=0000110111011000000110100010
C3=0000111111111111111110110000 D3=0011011101100000011010001000
C4=0011111111111111111011000000 D4=1101110110000001101000100000
C5=1111111111111111101100000000 D5=0111011000000110100010000011
C6=1111111111111110110000000011 D6=1101100000011010001000001101
C7=1111111111111011000000001111 D7=0110000001101000100000110111
C8=1111111111101100000000111111 D8=1000000110100010000011011101
C9=1111111111011000000001111111 D9=0000001101000100000110111011
C10=1111111101100000000111111111 D10=0000110100010000011011101100
C11=1111110110000000011111111111 D11=0011010001000001101110110000
C12=1111011000000001111111111111 D12=1101000100000110111011000000
C13=1101100000000111111111111111 D13=0100010000011011101100000011
C14=0110000000011111111111111111 D14=0001000001101110110000001101
C15=1000000001111111111111111101 D15=0100000110111011000000110100
C16=0000000011111111111111111011 D16=1000001101110110000001101000

『玖』 DES加密算法C语言实现

#include<iostream.h>
class SubKey{ //定义子密钥为一个类
public:
int key[8][6];
}subkey[16]; //定义子密钥对象数组

class DES{
int encipher_decipher; //判断加密还是解密
int key_in[8][8]; //用户原始输入的64位二进制数
int key_out[8][7]; //除去每行的最后一位校验位
int c0_d0[8][7]; //存储经PC-1转换后的56位数据
int c0[4][7],d0[4][7]; //分别存储c0,d0
int text[8][8]; //64位明文
int text_ip[8][8]; //经IP转换过后的明文
int A[4][8],B[4][8]; //A,B分别存储经IP转换过后明文的两部分,便于交换
int temp[8][6]; //存储经扩展置换后的48位二进制值
int temp1[8][6]; //存储和子密钥异或后的结果
int s_result[8][4]; //存储经S变换后的32位值
int text_p[8][4]; //经P置换后的32位结果
int secret_ip[8][8]; //经逆IP转换后的密文
public:
void Key_Putting();
void PC_1();
int function(int,int); //异或
void SubKey_Proction();
void IP_Convert();
void f();
void _IP_Convert();
void Out_secret();
};
void DES::Key_Putting() //得到密钥中对算法有用的56位
{
cout<<"请输入64位的密钥(8行8列且每行都得有奇数个1):\n";
for(int i=0;i<8;i++)
for(int j=0;j<8;j++){
cin>>key_in[i][j];
if(j!=7) key_out[i][j]=key_in[i][j];
}
}
void DES::PC_1() //PC-1置换函数
{
int pc_1[8][7]={ //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 i,j;
for(i=0;i<8;i++)
for(j=0;j<7;j++)
c0_d0[i][j]=key_out[ (pc_1[i][j]-1)/8 ][ (pc_1[i][j]-1)%8 ];
}
int DES::function(int a,int b) //模拟二进制数的异或运算,a和b为整型的0和1,返回值为整型的0或1
{
if(a!=b)return 1;
else return 0;
}
void DES::SubKey_Proction() //生成子密钥
{
int move[16][2]={ //循环左移的位数
1 , 1 , 2 , 1 ,
3 , 2 , 4 , 2 ,
5 , 2 , 6 , 2 ,
7 , 2 , 8 , 2 ,
9 , 1, 10 , 2,
11 , 2, 12 , 2,
13 , 2, 14 , 2,
15 , 2, 16 , 1
};
int pc_2[8][6]={ //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
};
for(int i=0;i<16;i++) //生成子密钥
{
int j,k;
int a[2],b[2];
int bb[28],cc[28];
for(j=0;j<4;j++)
for(k=0;k<7;k++)
c0[j][k]=c0_d0[j][k];
for(j=4;j<8;j++)
for(k=0;k<7;k++)
d0[j-4][k]=c0_d0[j][k];
for(j=0;j<4;j++)
for(k=0;k<7;k++){
bb[7*j+k]=c0[j][k];
cc[7*j+k]=d0[j][k];
}
for(j=0;j<move[i][1];j++){
a[j]=bb[j];
b[j]=cc[j];
}
for(j=0;j<28-move[i][1];j++){
bb[j]=bb[j+1];
cc[j]=cc[j+1];
}
for(j=0;j<move[i][1];j++){
bb[27-j]=a[j];
cc[27-j]=b[j];
}
for(j=0;j<28;j++){
c0[j/7][j%7]=bb[j];
d0[j/7][j%7]=cc[j];
}
for(j=0;j<4;j++) //L123--L128是把c0,d0合并成c0_d0
for(k=0;k<7;k++)
c0_d0[j][k]=c0[j][k];
for(j=4;j<8;j++)
for(k=0;k<7;k++)
c0_d0[j][k]=d0[j-4][k];
for(j=0;j<8;j++) //对Ci,Di进行PC-2置换
for(k=0;k<6;k++)
subkey[i].key[j][k]=c0_d0[ (pc_2[j][k]-1)/7 ][ (pc_2[j][k]-1)%7 ];
}
}
void DES::IP_Convert()
{
int IP[8][8]={ //初始置换IP矩阵
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
};
cout<<"你好,你要加密还是解密?加密请按1号键(输入1),解密请按2号键,并确定."<<'\n';
cin>>encipher_decipher;
char * s;
if(encipher_decipher==1) s="明文";
else s="密文";
cout<<"请输入64位"<<s<<"(二进制):\n";
int i,j;
for(i=0;i<8;i++)
for(j=0;j<8;j++)
cin>>text[i][j];
for(i=0;i<8;i++) //进行IP变换
for(j=0;j<8;j++)
text_ip[i][j]=text[ (IP[i][j]-1)/8 ][ (IP[i][j]-1)%8 ];
}

热点内容
武汉大学学生会辅导员寄语 发布:2021-03-16 21:44:16 浏览:612
七年级学生作文辅导学案 发布:2021-03-16 21:42:09 浏览:1
不屑弟高考成绩 发布:2021-03-16 21:40:59 浏览:754
大学毕业证会有成绩单 发布:2021-03-16 21:40:07 浏览:756
2017信阳学院辅导员招聘名单 发布:2021-03-16 21:40:02 浏览:800
查询重庆2018中考成绩查询 发布:2021-03-16 21:39:58 浏览:21
结业考试成绩怎么查询 发布:2021-03-16 21:28:40 浏览:679
14中医医师资格笔试考试成绩查分 发布:2021-03-16 21:28:39 浏览:655
名著赏析课程标准 发布:2021-03-16 21:27:57 浏览:881
北京大学商业领袖高端培训课程 发布:2021-03-16 21:27:41 浏览:919