yjm0105 阅读(732) 评论(9)

    下面是我将DES加密解密算法用C++编写并保存为des.h头文件,内容如下:
    [说明:其中的传入的字符数组我暂定义为256,传入、返回类型为字符的ASCII码一分为2的字符串(因为汉字的原因,我把每个ASCII字符修改为2个字节的16进制数字字符代替,1个汉字就是4个16进制数字字符)你可以酌情修改以符合你的需要~~C++编码的运用、风格方面还比较差,请宽恕我吧:p ]
点这打开des.h文件链接(本来想C#风格“插入代码”的,结果字符数有限制)

调用方式如下:
char *sRet=encrypt(char *sInfo , char *sKey, bool  bEnc);
//sInfo是欲加(解)密字符串,sKey是DES密钥字符串,bEnc为真(加密)、为假(解密),sRet为返回的加(解)密后字符串.

//----------------------------------------------------------------------------------------------
//des.h 
//***DES encrypt head file***
//***by yjm***
//***May. 2005***
#include <iostream.h>
#include <string.h>
char ch[256];//此处可修改一次接受传入的字符串长度(64的倍数)
unsigned int inf[64],inf1[64],k[64],parity(0),EP[48];//

char* encrypt(char pw[],char key[],bool jiami);
char NumToHex(int x);
char* HexToStr(char ch[]);
bool IsNum(char c);
int CharToNum(char c);
char* StrToHex(char ch[]);
int ip[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 };
 int ip1[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};
 //S盒(1,2,...8)
 int s[8][64]=
 {
  {
   14,0,4,15,13,7,1,4,2,14,15,2,11,13,8,1,
   3,10,10,6,6,12,12,11,5,9,9,5,0,3,7,8,
   4,15,1,12,14,8,8,2,13,4,6,9,2,1,11,7,
   15,5,12,11,9,3,7,14,3,10,10,0,5,6,0,13},
  {
   15,3,1,13,8,4,14,7,6,15,11,2,3,8,4,14, 
   9,12,7,0,2,1,13,10,12,6,0,9,5,11,10,5,
   0,13,14,8,7,10,11,1,10,3,4,15,13,4,1,2, 
   5,11,8,6,12,7,6,12,9,0,3,5,2,14,15,9},
  {
   10,13,0,7,9,0,14,9,6,3,3,4,15,6,5,10,
   1,2,13,8,12,5,7,14,11,12,4,11,2,15,8,1, 
   13,1,6,10,4,13,9,0,8,6,15,9,3,8,0,7,
   11,4,1,15,2,14,12,3,5,11,10,5,14,2,7,12},
  {
   7,13,13,8,14,11,3,5,0,6,6,15,9,0,10,3,
   1,4,2,7,8,2,5,12,11,1,12,10,4,14,15,9,
   10,3,6,15,9,0,0,6,12,10,11,1,7,13,13,8,
   15,9,1,4,3,5,14,11,5,12,2,7,8,2,4,14},
  {
   2,14,12,11,4,2,1,12,7,4,10,7,11,13,6,1, 
   8,5,5,0,3,15,15,10,13,3,0,9,14,8,9,6,
   4,11,2,8,1,12,11,7,10,1,13,14,7,2,8,13, 
   15,6,9,15,12,0,5,9,6,10,3,4,0,5,14,3},
  { 
   12,10,1,15,10,4,15,2,9,7,2,12,6,9,8,5,
   0,6,13,1,3,13,4,14,14,0,7,11,5,3,11,8,
   9,4,14,3,15,2,5,12,2,9,8,5,12,15,3,10,
   7,11,0,14,4,1,10,7,1,6,13,0,11,8,6,13},
  { 
   4,13,11,0,2,11,14,7,15,4,0,9,8,1,13,10, 
   3,14,12,3,9,5,7,12,5,2,10,15,6,8,1,6,
   1,6,4,11,11,13,13,8,12,1,3,4,7,10,14,7, 
   10,9,15,5,6,0,8,15,0,14,5,2,9,3,2,12},
  {
   13,1,2,15,8,13,4,8,6,10,15,3,11,7,1,4,
   10,12,9,5,3,6,14,11,5,0,0,14,12,9,7,2,
   1,2,11,1,4,14,1,7,9,4,12,10,14,8,2,13,
   0,15,6,12,10,9,13,0,15,3,3,5,5,6,8,11}
 };
 int pc1[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};
 int pc2[48]={ //密钥置换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};
 int 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, 1};
 int P[32]=  //置换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};


unsigned int cd[56],ki[16][48],kt[56],c[8],f[32];
void LS(int n)   //密钥左移函数
{
 int c0,d0,c1,d1;
 c0=cd[0];
 c1=cd[1];
 d0=cd[28];
 d1=cd[29];
 if(n==1||n==2||n==9||n==16)
 {
  for(int i=0;i<55;i++) 
   cd[i]=cd[i+1]; 
  cd[27]=c0;
  cd[55]=d0;
 }
 else{
  for(int i=0;i<54;i++)
   cd[i]=cd[i+2];
  cd[26]=c0;
  cd[27]=c1;
  cd[54]=d0;
  cd[55]=d1;
 }
}
char* encrypt(char pw[],char key[],bool jiami)

 char *p,*p1;
 p=pw;
 p1=key;
 int temp;
 //产生初始密钥流(64 bit).............可以自动扩展密钥长度 取前8字节
 for(int i=0;i<8;i++)
 {
  if(*p1=='\0')
   p1=key;  
  temp=int(*p1);
  for(int j=0;j<7;j++)
  {   
   k[8*i-j+6]=temp%2;
   parity+=temp%2;
   temp/=2;
  };
  k[8*(i+1)-1]=parity%2;
  parity=0;
  p1++;
 } 
//密钥置换 PC-1 
 for(i=0;i<28;i++)
 {
  cd[i]=k[pc1[i]-1];
  cd[i+28]=k[pc1[i+28]-1];   
 } 
 
//密钥置换 PC-2 &&产生Ki(i=1,2...16)
 for(i=0;i<16;i++)
 {
  LS(i+1);
  for(int j=0;j<48;j++)  
   ki[i][j]=cd[pc2[j]-1];  
 }

 //////////////////...................................................... 
 int len=strlen(pw),len1(0),*pp,*pp1;
 if(len%16>0)
  len1=16-len%16;
 pp=new int [(len+len1)*4];
 pp1=new int [(len+len1)*4];
 
 if(len1>0)
  for(int i=0;i<4*len1;i++)
   pp[len*4+i]=0;//不足64bit时用0补齐
 
 for(int t=0;t<len;t++)//明文组
 {
  temp=int(*(p+t));
  if(temp<=57&&temp>=48)
   temp-=48;
  else if(temp<=90&&temp>=65)
   temp-=55;
  for(int i=0;i<4;i++)
  {
   pp[4*t-i+3]=temp%2;
   temp/=2;   
  } 
 } 

 for(t=0;t<(len-1)/16+1;t++)//明文按64bit分组
 {
  for(int i=0;i<64;i++)  
    inf1[i]=pp[t*64+i]; 
   
  for(int m=0;m<64;m++) 
   inf[m]=inf1[ip[m]-1]; 
  //距阵分左右2边 L0 (0-31)和 R0(32-63)  
  //f函数运算  
  for(int kx=0;kx<16;kx++)
  {   //对Ri作E扩展   
   for(int j=0;j<48;j++)
   {   //A(32bit)⊕E→E(A)(48bit) ...   E(A)⊕J
    if(jiami)
     EP[j]=inf[E[j]+31]^ki[kx][j];//加密********************
    else
     EP[j]=inf[E[j]+31]^ki[15-kx][j];//解密*****************
   }  
   for(j=0;j<8;j++)
   {
    temp=EP[j*6]*32+EP[j*6+1]*16+EP[j*6+2]*8+EP[j*6+3]*4+EP[j*6+4]*2+EP[j*6+5];
    c[j]=s[j][temp];
    for(int k=0;k<4;k++)//48bit--->32bit
    {
     EP[4*j+3-k]=c[j]%2;
     c[j]/=2;   
    }     
   }   
   for(j=0;j<32;j++)
   {    //P置换→f(A,J)(32bit)   
    f[j]=inf[j]^EP[P[j]-1];//L⊕f(R,K)
    if(kx!=15)
    {
     inf[j]=inf[j+32];
     inf[j+32]=f[j];
    }
    else   
     inf[j]=f[j];
   }
   
  }
  
  //逆初始置换IP-1
  for(i=0;i<64;i++) 
   pp1[64*t+i]=inf[ip1[i]-1]; 
 }

 temp=(len+len1); 
 char tt[256];//对应ch的长度
 for(i=0;i<temp;i++) 
  tt[i]=NumToHex(pp1[4*i]*8+pp1[4*i+1]*4+pp1[4*i+2]*2+pp1[4*i+3]); 
 tt[temp]='\0';///
 strcpy(ch,tt);

 delete []pp;
 delete []pp1;

 return ch;
}
char NumToHex(int x)

 if(x>=0&&x<=9)
  return char(x+48);
 if(x>=10&&x<=15)
  return char(x+55);
 return '?';
}
char* HexToStr(char ch[])
{
 int len=strlen(ch)/2,temp;
 for(int i=0;i<len;i++)
 { 
  temp=CharToNum(ch[2*i])*16+CharToNum(ch[2*i+1]);
  if(temp>127)
   temp=128-temp;
  ch[i]=char(temp); 
 }
 ch[len]='\0';
 return ch;
}
bool IsNum(char c)
{
 if(c<='9'&&c>='0')
  return true;
 else
  return false;
}
int CharToNum(char c)
{
 if(c<='9'&&c>='0')
  return int(c)-48;
 if(c<='Z'&&c>='A')
  return int(c)-55;
 if(c<='z'&&c>='a')
  return int(c)-87;
 return -1;
}
char* StrToHex(char* ch)
{
 int len=lstrlen(ch),n;
 char str[256];
 memset(str,0,256);
 memcpy(str,ch,strlen(ch));
 for(int i=len-1;i>=0;i--)
 {
  n=int(str[i]);
  if(n<0)
   n=128-n; 
  str[2*i]=NumToHex((n&0xf0)/16);
  str[2*i+1]=NumToHex(n&0x0f); 
 }
 //follow for DES's 64bit ////
 ///////////////////////////////
// str[len*2]='\0';
 strcpy(ch,str);
 
 return ch; 
}


评论列表
netsin
re: DES算法的C++编写实现
除了new/delete,完全看不到C++的影子,我把new 改成malloc,delete[] 改成 free,这个就是DES 的C实现了,:p
流云
但偶只学过C++的语法
?:-)
netsin
re: DES算法的C++编写实现
sorry,偶乱说的,:$
流云
To:netsin
你说的也有道理啊,不必谦退嘛
大猫
re: DES算法的C++编写实现
des算法我感觉好理解,可是调试起来比较难,我编了des的c语言实现,和书上的算法一模一样,可是解密后不是原来的值,郁闷,想请教一下有没有测试数据?
流云
To: 大猫
当然,可以加密并解密还原
Jay
re: DES算法的C++编写实现
解密后不是原来的明文。。。。
流云
re: Jay
原来写的很烂,也没说清楚:(
下面给出我怎么用的@@

#include<iostream.h>
#include "des.h"

int main()
{   
char *s="";
char buf[256]="测试";
char *key="key";
cout<<"STR明文输入:"<<buf<<endl;
s=StrToHex(buf);
cout<<"HEX加密输入:"<<s<<endl;

s=encrypt(s,key,1);
cout<<"HEX加密输出:"<<s<<endl;
cout<<endl;

cout<<"HEX解密输入:"<<s<<endl;
s=encrypt(s,key,0);
cout<<"HEX解密输出:"<<s<<endl;

s=HexToStr(s);
cout<<"STR解密输出:"<<s<<endl;

    return 0;
}
Zzx
re: DES算法的C++编写实现
有很急的问题。能用QQ聊吗?我QQ277836257
请注明C++谢谢。希望你能帮助我

发表评论
切换编辑模式