请问如何用C语言(或C++)实现高效率的DES算法

供稿:hz-xin.com     日期:2025-01-13
用C++或者C语言实现DES算法,明文learing,密钥computer.求出密文(写出过程)

#include

DWORDLONG dwlKey_PC_1[64]={
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,0};

DWORDLONG dwlKey_PC_2[64]={
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,0};

DWORDLONG dwlData_IP[65]={
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,0};

DWORDLONG dwlData_Expansion[64]={
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,0};


DWORDLONG dwlData_P[33]={
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,0};

DWORDLONG dwlData_FP[65]={
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,0};

DWORDLONG OS[512]={
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,

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,

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,

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,

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,

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,

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,

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
};
-------------------------------------
des.cpp
-------------------------------------

/*注意:这只是标准DES算法的例子,所以速度并不是很快,不适用于大量数据加密的场*/
/*合.UNIX的密码也采用DES,不过它在里面加了点其它的东西.所以结果和DES的结果 */
/*不一样. 由于使用了WINDOWS类库,所以必须在WINDOWS环境下编译. */
/**************************************************************************/

#include
#include
#include
#include
#include "Schedle.h"

class CShift{
public:
DWORDLONG mask[16];
int step[16];
CShift(){
for(int i=0;i step=2;
mask=0xc000000;
}
step[0]=step[1]=step[8]=step[15]=1;
mask[0]=mask[1]=mask[8]=mask[15]=0x8000000;
}
};

class CDES{

public:

CDES(){
m_dwlKey=0;
m_dwlData=0;
ConvertTableToMask(dwlKey_PC_1,64);
//PrintTable(dwlKey_PC_1,7,8);
ConvertTableToMask(dwlKey_PC_2,56);
ConvertTableToMask(dwlData_IP,64);
ConvertTableToMask(dwlData_Expansion,32);
ConvertTableToMask(dwlData_FP,64);
ConvertTableToMask(dwlData_P,32);
Generate_S();

}
void PrintBit(DWORDLONG);
void EncryptKey(char *);
unsigned char* EncryptData(unsigned char *);
unsigned char* DescryptData(unsigned char*);

private:
void ConvertTableToMask(DWORDLONG *,int);
void Generate_S(void);
void PrintTable(DWORDLONG*,int,int);
DWORDLONG ProcessByte(unsigned char*,BOOL);
DWORDLONG PermuteTable(DWORDLONG,DWORDLONG*,int);
void Generate_K(void);
void EncryptKernel(void);
DWORDLONG Generate_B(DWORDLONG,DWORDLONG*);
/*For verify schedule permutation only*/
DWORDLONG UnPermuteTable(DWORDLONG,DWORDLONG*,int);
/**************************************/
DWORDLONG dwlData_S[9][4][16];
CShift m_shift;
DWORDLONG m_dwlKey;
DWORDLONG m_dwlData;
DWORDLONG m_dwl_K[17];
};

void CDES::EncryptKey(char *key){

printf("
Original Key: %s",key);
m_dwlKey=ProcessByte((unsigned char*)key,TRUE);
//PrintBit(m_dwlKey);
m_dwlKey=PermuteTable(m_dwlKey,dwlKey_PC_1,56);
//PrintBit(m_dwlKey);
Generate_K();
//printf("
******************************************
");
}

void CDES::Generate_K(void){

DWORDLONG C[17],D[17],tmp;

C[0]=m_dwlKey>>28;
D[0]=m_dwlKey&0xfffffff;

for(int i=1;i tmp=(C[i-1]&m_shift.mask[i-1])>>(28-m_shift.step[i-1]);
C=((C[i-1] tmp=(D[i-1]&m_shift.mask[i-1])>>(28-m_shift.step[i-1]);
D=((D[i-1] m_dwl_K=(C m_dwl_K=PermuteTable(m_dwl_K,dwlKey_PC_2,48);
}
}

DWORDLONG CDES::ProcessByte(unsigned char *key,BOOL shift){

unsigned char tmp;
DWORDLONG byte=0;
int i=0;

while(i while(*key){
if(byte!=0)
byte tmp=*key;
if(shift)
tmp byte│=tmp;
i++;
key++;
}
if(i byte i++;
}
return byte;
}

DWORDLONG CDES::PermuteTable(DWORDLONG dwlPara,DWORDLONG* dwlTable,int nDestLen)
{

int i=0;
DWORDLONG tmp=0,moveBit;

while(i moveBit=1;
if(dwlTable&dwlPara){
moveBit tmp│=moveBit;
}
i++;
}
return tmp;
}

DWORDLONG CDES::UnPermuteTable(DWORDLONG dwlPara,DWORDLONG* dwlTable,int nDestLe
n){

DWORDLONG tmp=0;
int i=nDestLen-1;

while(dwlPara!=0){
if(dwlPara&0x01)
tmp│=dwlTable;
dwlPara>>=1;
i--;
}
return tmp;
}

void CDES::PrintTable(DWORDLONG *dwlPara,int col,int row){

int i,j;
for(i=0;i printf("
");
getch();
for(j=0;j PrintBit(dwlPara[i*col+j]);
}
}

void CDES::PrintBit(DWORDLONG bitstream){

char out[76];
int i=0,j=0,space=0;

while(bitstream!=0){
if(bitstream&0x01)
out[i++]='1';
else
out[i++]='0';
j++;
if(j%8==0){
out[i++]=' ';
space++;
}

bitstream=bitstream>>1;
}
out='\0';
strcpy(out,strrev(out));
printf("%s **:%d
",out,i-space);
}

void CDES::ConvertTableToMask(DWORDLONG *mask,int max){

int i=0;
DWORDLONG nBit=1;

while(mask!=0){
nBit=1;
nBit mask[i++]=nBit;
}
}

void CDES::Generate_S(void){

int i;
int j,m,n;
m=n=0;
j=1;

for(i=0;i dwlData_S[j][m][n]=OS;
n=(n+1)%16;
if(!n){
m=(m+1)%4;
if(!m)
j++;
}
}
}

unsigned char * CDES::EncryptData(unsigned char *block){

unsigned char *EncrytedData=new unsigned char(15);

printf("
Original Data: %s
",block);
m_dwlData=ProcessByte(block,0);
//PrintBit(m_dwlData);
m_dwlData=PermuteTable(m_dwlData,dwlData_IP,64);
EncryptKernel();
//PrintBit(m_dwlData);
DWORDLONG bit6=m_dwlData;
for(int i=0;i EncrytedData[7-i]=(unsigned char)(bit6&0x3f)+46;
bit6>>=6;
}
EncrytedData[11]='\0';
printf("
After Encrypted: %s",EncrytedData);

for(i=0;i EncrytedData[7-i]=(unsigned char)(m_dwlData&0xff);
m_dwlData>>=8;
}
EncrytedData[8]='\0';


return EncrytedData;
}

void CDES::EncryptKernel(void){

int i=1;

DWORDLONG L[17],R[17],B[9],EK,PSB;
L[0]=m_dwlData>>32;
R[0]=m_dwlData&0xffffffff;

for(i=1;i L=R[i-1];
R[i-1]=PermuteTable(R[i-1],dwlData_Expansion,48);//Expansion R
EK=R[i-1]^m_dwl_K;//E Permutation
PSB=Generate_B(EK,B);//P Permutation
R=L[i-1]^PSB;
}

R[16] m_dwlData=R[16]│L[16];
m_dwlData=PermuteTable(m_dwlData,dwlData_FP,64);
}

unsigned char* CDES::DescryptData(unsigned char *desData){

int i=1;
unsigned char *DescryptedData=new unsigned char(15);
DWORDLONG L[17],R[17],B[9],EK,PSB;
DWORDLONG dataPara;

dataPara=ProcessByte(desData,0);
dataPara=PermuteTable(dataPara,dwlData_IP,64);

R[16]=dataPara>>32;
L[16]=dataPara&0xffffffff;

for(i=16;i>=1;i--){
R[i-1]=L;
L=PermuteTable(L,dwlData_Expansion,48);//Expansion L
EK=L^m_dwl_K;//E Permutation
PSB=Generate_B(EK,B);//P Permutation
L[i-1]=R^PSB;
}

L[0] dataPara=L[0]│R[0];
dataPara=PermuteTable(dataPara,dwlData_FP,64);

//PrintBit(dataPara);

for(i=0;i DescryptedData[7-i]=(unsigned char)(dataPara&0xff);
dataPara>>=8;
}
DescryptedData[8]='\0';
printf("
After Decrypted: %s
",DescryptedData);

return DescryptedData;
}

DWORDLONG CDES::Generate_B(DWORDLONG EKPara,DWORDLONG *block){

int i,m,n;
DWORDLONG tmp=0;

for(i=8;i>0;i--){
block=EKPara&0x3f;
m=(int)(block&0x20)>>4;
m│=block&0x01;
n=(int)(block >2;
block=dwlData_S[m][n];
EKPara>>=6;
}

for(i=1;i tmp│=block;
tmp }
tmp>>=4;
tmp=PermuteTable(tmp,dwlData_P,32);

return tmp;
}

void main(void){

CDES des;
des.EncryptKey("12345678");
unsigned char *result=des.EncryptData((unsigned char*)"DemoData");
des.DescryptData(result);
}

上学期交的作业,已通过老师在运行时间上的测试
#include
#include

unsigned long prime1,prime2,ee;

unsigned long *kzojld(unsigned long p,unsigned long q) //扩展欧几里得算法求模逆
{
unsigned long i=0,a=1,b=0,c=0,d=1,temp,mid,ni[2];
mid=p;
while(mid!=1)
{
while(p>q)
{p=p-q;mid=p;i++;}
a=c*(-1)*i+a;b=d*(-1)*i+b;
temp=a;a=c;c=temp;
temp=b;b=d;d=temp;
temp=p;p=q;q=temp;
i=0;
}
ni[0]=c;ni[1]=d;
return(ni);
}

unsigned long momi(unsigned long a,unsigned long b,unsigned long p) //模幂算法
{
unsigned long c;
c=1;
if(a>p) a=a%p;
if(b>p) b=b%(p-1);
while(b!=0)
{
while(b%2==0)
{
b=b/2;
a=(a*a)%p;
}
b=b-1;
c=(a*c)%p;
}
return(c);
}

void RSAjiami() //RSA加密函数
{
unsigned long c1,c2;
unsigned long m,n,c;
n=prime1*prime2;
system("cls");
printf("Please input the message:
");
scanf("%lu",&m);getchar();
c=momi(m,ee,n);
printf("The cipher is:%lu",c);
return;
}

void RSAjiemi() //RSA解密函数
{
unsigned long m1,m2,e,d,*ni;
unsigned long c,n,m,o;
o=(prime1-1)*(prime2-1);
n=prime1*prime2;
system("cls");
printf("Please input the cipher:
");
scanf("%lu",&c);getchar();
ni=kzojld(ee,o);
d=ni[0];
m=momi(c,d,n);
printf("The original message is:%lu",m);
return;
}

void main()
{unsigned long m;
char cho;
printf("Please input the two prime you want to use:
");
printf("P=");scanf("%lu",&prime1);getchar();
printf("Q=");scanf("%lu",&prime2);getchar();
printf("E=");scanf("%lu",&ee);getchar();
if(prime1<prime2)
{m=prime1;prime1=prime2;prime2=m;}
while(1)
{
system("cls");
printf("*******RSA密码系统*******
");
printf("Please select what do you want to do:
");
printf("1.Encrpt.
");
printf("2.Decrpt.
");
printf("3.Exit.
");
printf("Your choice:");
scanf("%c",&cho);getchar();
switch(cho)
{case '1':RSAjiami();break;
case '2':RSAjiemi();break;
case '3':exit(0);
default:printf("Error input.
");break;
}
getchar();
}
}

试试这个吧:
#include<stdio.h>

main(){

int i,temp,temp1,a[8],k[10],k1[8],k2[8],t[8],t1[8],t2[8],p4[4],m[8];
int p10[10]={3,5,2,7,4,10,1,9,8,6};
int p8[8]={6,3,7,4,8,5,10,9};
int ip[8]={2,6,3,1,4,8,5,7};
int ip1[8]={4,1,3,5,7,2,8,6};
int ep[8]={4,1,2,3,2,3,4,1};
int s0[4][4]={{1,0,3,2},{3,2,1,0},{0,2,1,3},{3,1,3,2}};
int s1[4][4]={{0,1,2,3},{2,0,1,3},{3,0,1,0},{2,1,0,3}};
char c='c';

while(c=='c'||c=='C'){
printf("\n\n\n\n\n\********************************************\n\n");
printf("This is the S-DES program for our BOOK !");
printf("\n\n\nPlease input a[8] 8bit MingWen:");
for(i=0;i<8;i++)
scanf("%1d",&a[i]);
/* for(i=0;i<8;i++)
printf("%1d",a[i]); */
printf("\n\nPlease input k[10] 10bit MiShi:");
for(i=0;i<10;i++)
scanf("%1d",&k[i]);
/* for(i=0;i<10;i++)
printf("%1d",k[i]); */

/*下面是算K1与K2*/
for(i=0;i<10;i++)
t[i]=k[p10[i]-1];
temp=t[0];
for(i=0;i<9;i++)
t[i]=t[i+1];
t[9]=t[4];
t[4]=temp;
for(i=0;i<8;i++)
k1[i]=t[p8[i]-1];
temp=t[0];
temp1=t[1];
for(i=0;i<8;i++)
t[i]=t[i+2];
t[8]=t[3];
t[9]=t[4];
t[3]=temp;
t[4]=temp1;
for(i=0;i<8;i++)
k2[i]=t[p8[i]-1];

/*下面是两次f函数运算与ip,ip`,SW得最后密文*/
for(i=0;i<8;i++)
t[i]=a[ip[i]-1];

for(i=0;i<8;i++)
t1[i]=t[ep[i]+4-1];
for(i=0;i<8;i++)
t1[i]=t1[i]^k1[i];
temp=s0[t1[0]*2+t1[3>[t1[1]*2+t1[2>;
temp1=s1[t1[4]*2+t1[7>[t1[5]*2+t1[6>;
p4[0]=temp/2;
p4[1]=temp%2;
p4[2]=temp1/2;
p4[3]=temp1%2;
for(i=0;i<4;i++)
t2[i+4]=t1[i]^p4[i];

for(i=0;i<8;i++)
t1[i]=t2[ep[i]+4-1];
for(i=0;i<8;i++)
t1[i]=t1[i]^k2[i];
temp=s0[t1[0]*2+t1[3>[t1[1]*2+t1[2>;
temp1=s1[t1[4]*2+t1[7>[t1[5]*2+t1[6>;
p4[0]=temp/2;
p4[1]=temp%2;
p4[2]=temp1/2;
p4[3]=temp1%2;
for(i=0;i<4;i++)
t2[i]=t1[i]^p4[i];

for(i=0;i<8;i++)
m[i]=t2[ip1[i>;

printf("\nMiWen Shi : ");
for(i=0;i<8;i++)
printf("%d",m[i]);

printf("\n\nC For Continue !\nAny Else Key To Exit !\n");
c=getch();

}/*END while*/

}

开源的有很多啦,比如这个
http://www.ka9q.net/code/des/
汇编版和C语言版都有

c++和c语言区别
1、C++是一个开放标准,旨在实现速度和性能和关键性的高性能系统,有很多令人印象深刻的项目使用Lander,AdobeAcrobatReader等语言设计。而C是一个结构化语言,C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现过程(事务)控制)。2、C++使开发人员能够使用非常...

c语言和c++语言有什么区别?
一个函数被编译得连名字也不知道怎么样了.这么一来.如果SDK提供的是C++编译器提供了LIB.那么可以说就无法编译任何一个完整的WIN程序.更加不用说什么混合语言编程.现在,VC编译器提供了个extern语句.当出现extern 'C'语句,括号里的函数将以C方式经过编译器.从而使提供库程序方便那么点.C语言与C++的...

C++中如何实现C语言中类似于"printf("%3d",a);"中%3d的功能?
设置cout对象的列宽就可了啦!std::cout.width(X);可将列宽设置为X个字符 例程:\/\/--- include <iostream> int main(void){ std::cout.width(5);std::cout<<2;std::cout.width(3);std::cout<<5<<std::endl;return 0;} \/\/--- ...

求c++语言解决实际问题~~~很急的
2019-08-10 求c语言题目 c++ 很急今天之内就要 求1\/1!-1\/2! 1 2012-01-09 求了C++语言编程试题 急~关系终生 高手们 多多帮忙啊 ~... 2016-01-02 求用c++语言来编写下图的三道题 本人新人没学会这东西 求急... 2012-03-13 有精通计算机C++语言的朋友没有,求帮助,急急急~~~ 1 2018-12-04...

如何用C语言编程出可视化界面
对于那些需要快速开发图形界面程序的开发者来说,使用C++或者Java等面向对象语言更为合适。然而,对于那些对性能要求极高,且熟悉C语言的开发者,通过调用API函数,仍然可以实现功能强大的图形界面程序。例如,开发一些对响应时间要求较高的嵌入式系统应用,或者需要直接与硬件进行交互的程序。总结来说,虽然C...

精通C语言和C++能找到哪方面工作
2. 后端开发 主流的后端开发语言就那么几种,以Java、C++领衔,Python和Go紧跟其后。3. 游戏开发 掌握了C++基本语法之后,开发游戏也依然是一个不错的选择,目前工业级别的3D游戏引擎仍然是用C或C++编写的。虽然以个人能力无法去完成一个庞大的网络游戏,但是从简单开始,编写一些小游戏,然后逐渐深入,...

C 语言与 C++ 语言混合编程的方法
完成代码层面的准备工作后,可以通过动态链接库或直接链接C++和C语言的.o文件来实现混编。动态链接库方式下,编译得到的.so文件与C语言程序链接生成可执行文件,通过指定动态链接库搜索目录启动程序。第二种方法是将所有cpp文件编译为.o文件,然后与C语言.o文件链接生成可执行文件。实际项目中,选择何种方法...

C语言和C++之间的转换问题
c++语言是c语言发展起来的,所以继承了c语言几乎所有的特点,但c++语言又有自己的个性。c语言是一种面向过程的编程语言,而c++主要是面向过程的,因此c++有类的概念,而c语言就没有。c++的功能强大,编译器复杂,适合高端程序的设计和编辑,c语言的编译器简易,适合低端程序。

C语言与C++语言能够共用吗?
可以共用的。具体取决于使用的编译器。使用C编译器:C编译器是不支持编译C++代码的。因为C++有很多C语言标准没有定义的扩展。所以同时存在纯C和C++代码的话是不能通过C编译器的编译的。使用C++编译器C++是C语言的扩展延伸,C++设计之初就考虑了完全兼容C语言的。所以纯C或是混合C\/C++项目都是可以被C++...

为什么现在的操作系统基本上用C语言来实现
5、编译器本身最好是由该语言自己完成的(大部分语言的编译器都是用C\/C++写的);6、开发者可以很方便的扩展、改造、或者使用第三方的运行库(大部分语言的库都无法修改);7、开发者众多(小众语言就不行);8、该语言开发操作系统的资料要足够完善。所以总结下来,C语言是首选。当然了,不是说其它...