// DES加密算法的实现,由口令字导出加密用的密钥,明文分组大小为64bit,
//密文分组大小为64bit,明文二进制信息存放于《明文二进制表示.dat》
//密钥二进制存放于《密钥二进制表示.dat》,密文存放于《密文二进制.dat》中
#include "stdafx.h"
#include <iostream.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <memory.h>
#include "malloc.h"
#include "conio.h"
const unsigned int s[4][4]=//压缩函数每步左循环移位的位数,列号表示轮数
{
{7,12,17,22},{5,9,14,20},
{4,11,16,23},{6,10,15,21}
};
const unsigned long t[64]={//t[i]=4294967296*fabs(sin(i+1));
0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,0xa679438e,0x49b40821,
0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,
0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,
0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,
0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,
0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391
};//常数表
const int serial[64]=
{
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,//直接使用前16个字,i是迭代的步数
1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,//使用字的次序为(1+5i)mod 16
5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,//使用字的次序为(5+3i)mod 16
0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9//使用字的次序为(7i)mod 16
};
int Ki[16][48];//16轮的子密钥
int L[32]={0};
int R[32]={0};//明文比特的左右两半
int code[64]={0};//密文
void func(unsigned long& a,
unsigned long b,
unsigned long c,
unsigned long d,
unsigned long M,
unsigned long t,
int s,//s为循环移位的次数
int turn)
{
unsigned long temp;
switch(turn)//4轮中每一轮的基本逻辑函数
{
case 0:
temp=(b&c)|((~b)&d);//F
break;
case 1:
temp=(d&b)|((~d)&c);//G
break;
case 2:
temp=b^c^d;//H
break;
case 3:
temp=c^(b|(~d));//I
break;
}
temp+=M+t+a;//M是消息第q个分组中的第k个字,X[K]=M[q*16+K]
_asm//插入汇编语言
{
mov ecx,s
rol temp,cl
}
a=b+temp;
}
void MD512(const unsigned long M[16],unsigned long hash[4])
{
int i,j,index=0;
for (i=0;i<4;i++)//十六步的迭代,周期为4
for (j=0;j<4;j++)
{
func(hash[0],hash[1],hash[2],hash[3],M[serial[index]],t[index],s[i][0],i);
index++;
func(hash[3],hash[0],hash[1],hash[2],M[serial[index]],t[index],s[i][1],i);
index++;
func(hash[2],hash[3],hash[0],hash[1],M[serial[index]],t[index],s[i][2],i);
index++;
func(hash[1],hash[2],hash[3],hash[0],M[serial[index]],t[index],s[i][3],i);
index++;
}
}
void MD5(char* M,int nLen,unsigned long output[4])
{
int i,j;
unsigned long Hash[4]={0x67452301,0xefcdab89,0x98badcfe,0x10325476};
unsigned long hash[4];
/////////////////////////////////////////////////////////
//填充
__int64 BitsLen=nLen*8;
int oldlen=nLen;
while(nLen%64!=56)//比特长在模512下为448
{
M[nLen++]=0;
}
M[oldlen]=0x80;//填充的第一位为1,其它全为0,故是ox80
*(__int64*)(M+nLen)=BitsLen;
nLen+=8;
/////////////////////////////////////////////////////////
//开始处理分组
for (i=0;i<nLen;i+=64)
{
memcpy(hash,Hash,sizeof(long)*4);
MD512((const unsigned long*)&M[i],hash);//处理512bits分组
for (j=0;j<4;j++)
Hash[j]+=hash[j];//最后
}
/////////////////////////////////////////////////////////
//处理输出。
for (i=0;i<4;i++)
for (j=3;j>=0;j--)
{
*((char*)(output+i)+j)=*((char*)(Hash+i)+3-j);
}
}//MD512结束
void mingwen()
{
FILE *fpmingwen;
char szMessage[8]={'1','1','1','1','1','1','1','1'};
int message[64]={0};
int midn[8]={0};
int i,j;
printf("input a 8th string to be encrypted:\n>>>");
for(i=0;i<8;i++)scanf("%c",&szMessage[i]);
for(i=0;i<8;i++){
for(j=0;j<8;j++){
midn[j]=szMessage[i]%2;
szMessage[i]=szMessage[i]/2;
}
for(j=7;j>=0;j--)
message[8*i+7-j]=midn[j];
}
//for(j=0;j<8;j++){ if(message[j]==0)printf("0");else printf("1"); }
if((fpmingwen=fopen("明文二进制表示.dat","w"))==NULL)
{
printf("can not open the file\n");//exit(0);
}
else
{
for(i=0;i<64;i++)fprintf(fpmingwen,"%d\n",message[i]);
}
fclose(fpmingwen);
/*FILE *fptext;
struct words//保存明文的内容
{char word[8];
struct words *next;
};
struct words *head;
struct words* p1,*p2;
int size;
size=sizeof(head->word);
//printf("输入电文文件名(如file.txt):\n");
//gets(filename);
fptext=fopen("明文.txt","r");
if(fptext==NULL)
printf("打开文件失败。\n");
else {
p1=(struct words*)malloc(sizeof(struct words));
head=p1;
while(!feof(fptext))
{fread(p1->word,size,1,fptext);
p2=p1;
p1=(struct words*)malloc(sizeof(struct words));
p2->next=p1;
}
p2->next=NULL;
p2=NULL;
free(p1);
p1=NULL;
p1=head;
printf("电文的内容如下:\n");
while(p1!=NULL)
{printf("%s\t",p1->word);
p1=p1->next;
}
printf("\n");
}
fclose(fptext);*/
}
void miyaochsh()
{ int i,j;
FILE *fpkey;
char password[1000]={'1','1','1','1','1','1','1','1'};
int key[64]={0};//分组加密的密钥
int mid=0;
printf("\ninput your password:\n>>>");
scanf("%s",password);
unsigned long output[4];
MD5(password,strlen(password),output);
//以下是选取口令password的压缩值的前64比特作为分组加密的密钥
for(i=0;i<2;i++)
{ for(j=0;j<32;j++)//二进制表示
{ key[i*32+j]=output[i]%2;
output[i]=output[i]/2;}
for(j=0;j<16;j++)//逆序排列
{ mid= key[i*32+j];
if(i==0){key[j]=key[31-j]; key[31-j]=mid;}
else{key[32+j]=key[63-j]; key[32+j]=mid;}
}
}
if((fpkey=fopen("密钥二进制表示.dat","w"))==NULL)
{
printf("can not open the file\n");//exit(0);
}
else
{
for(i=0;i<64;i++)fprintf(fpkey,"%d\n",key[i]);
}
fclose(fpkey);
}
//以下是明文初始置换和各轮加密子密钥的生成
void initial(int opflag)//opfalg=0表示加密,=1表示解密
{
FILE *fp;
int flag=opflag;
char *filename=NULL;
int m[64],m1[64],k[64],i,j,k0[56],C[56],cnun,CMID[28],DMID[28];
//以下的数组是用于密钥变换的
int CK[16][28],DK[16][28];
/////////end
int ip[64]={58,50,42,34,26,18,10,2,//初始置换IP
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};
///////////以下的两个表为DES密钥编排中使用的表
int PC_1[56]={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 PC_2[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};
int cir[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};//每轮循环的次数
if(flag==0) filename="明文二进制表示.dat";//jiami
else filename="密文二进制表示.dat";
fp=fopen(filename,"r");
if(flag==0) printf("明文二进制:\n");
else printf("密文二进制:\n");
for(i=0;i<64;i++)
{
fscanf(fp,"%d\n",&m[i]);
printf("%d",m[i]);
}
fclose(fp);
fp=fopen("密钥二进制表示.dat","r");
for(i=0;i<64;i++)
fscanf(fp,"%d\n",&k[i]);
fclose(fp);
for(i=0;i<64;i++)
m1[i]=m[ip[i]-1];
for(i=0;i<32;i++)
L[i]=m1[i];//明文左侧的初始化
for(i=32;i<64;i++)
R[i-32]=m1[i];//明文右侧的初始化
for(i=0;i<56;i++)//密钥置换选择1
k0[i]=k[PC_1[i]-1];
des.rar_DES口令
版权申诉
20 浏览量
2022-09-24
01:02:17
上传
评论
收藏 6KB RAR 举报
APei
- 粉丝: 64
- 资源: 1万+
最新资源
- c51_2_2.c
- ASCII American Standard Code for Information Interchange
- 一个chm格式的 SQL 函数手册-SQL语言手册文档
- 计算当前月份的天数和剩余天数
- 基于ARM的指令调度和延迟分支
- 基于Vue和TypeScript的极简聊天应用设计源码 - HasChat
- 基于Vue2全家桶和Zcool数据的图片收集网站设计源码 - cool-picture
- 基于C和C++的二维绘制工具设计源码 - DrawPro
- Object.defineProperty 的 IE 补丁object-defineproperty-ie-master.zip
- 整卷预览.mhtml
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈