DES加解密算法是一个挺老的算法了,现在给出它的C语言版。
des.h
#ifdef __cplusplus
extern "C" {
#endif void setKey(const char key[]);
char* des(const char datas[]);
char * dedes(const char datas[]); #ifdef __cplusplus
}
#endif
des_tables.h
char table_IP[] /* 初始置换表 IP */
= {
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , ,
}; const static char table_FP[] /* 末置换表 */
= {
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , ,
}; //= {
// 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
//}; char table_PC_1[] /* 密钥置换表PC_1 */
= {
, , , , , , , , , , , , , ,
, , , , , , , , , , , , , ,
, , , , , , , , , , , , , ,
, , , , , , , , , , , , ,
}; char table_PC_2[] /* 压缩置换表 PC_2 */
= {
, , , , , , , , , , , ,
, , , , , , , , , , , ,
, , , , , , , , , , , ,
, , , , , , , , , , ,
}; char table_S[][] /* 48->32 bit compression tables*/
= { /* S[1] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
/* S[2] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
/* S[3] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
/* S[4] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
/* S[5] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
/* S[6] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
/* S[7] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
/* S[8] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , ,
}; char table_P[] /* P 盒置换 */
= { , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , ,
}; char table_E[]
= {
, , , , , , , , , , , ,
, , , , , , , , , , , ,
, , , , , , , , , , , ,
, , , , , , , , , , ,
}; char table_move[]
={
,,,,
,,,,
,,,,
,,,
};
des.c
#include<stdio.h>
#include<string.h>
#include"des_tables.h"
#include"des.h" //保存这16轮的加密密钥<64位>
char keys[][];
//存着经过压缩置换后的 key
char key_48[][]; char data[];
//s盒置换结果缓冲区
char data_32[];
char *data_left;
char *data_right; //密钥置换
void fun_InitReplacementKey(){
register int i,j,l=;
register unsigned int k;
register char *to_pos = keys[];
memset(to_pos,,);
for(i=,l=;i<;i++){
for(j=;j>;j--){
k = table_PC_1[l++]-;
*to_pos = (*to_pos)| (( (*(keys[]+(k>>)) >>( - (k&0x07) ))&0x01 )<<j);
} to_pos++;
}
} //对密钥进行移位,并存在接下来下面的字节中
void fun_MoveKey(int len , char*offset, char *dist){
/////////////////////////
///错误了!!!! 是分两块进行循环移位 !!!!!!!
///< 已修改 ! 需要分左右部分 > register int i = len;
unsigned char firstBit;
static unsigned char *tmp;
tmp =(unsigned char*)dist;
memcpy(tmp,offset,);
firstBit =(unsigned char)tmp[];
firstBit = firstBit>>(-len); //左边部分循环左移
for(i=;i< ;i++){
tmp[i] = (tmp[i]&0xfe) <<len ;
tmp[i] = tmp[i]|((tmp[i+]>>(-len))&0xff);
tmp[i] = tmp[i]&0xfe;
} tmp[i] = (tmp[i] &0xfe)<<len;
tmp[i] = tmp[i]|(firstBit<<);
tmp[i] = tmp[i]&0xfe; firstBit =(unsigned char)tmp[++i];
firstBit = firstBit>>(-len); //右边部分循环左移
for(i;i<;i++){
tmp[i] = (tmp[i]&0xfe) <<len ;
tmp[i] = tmp[i]|((tmp[i+]>>(-len))&0xff);
tmp[i] = tmp[i]&0xfe;
}
tmp[i] = (tmp[i] &0xfe)<<len;
tmp[i] = tmp[i]|(firstBit<<);
tmp[i] = tmp[i]&0xfe; } //对密钥进行压缩置换并保存到指定位置
void fun_ReplacementCompressKey(char* offset,char *dist){
//压缩置换是在 0-56位进行.需要先对64位密钥进行压缩为56位在进行48位选择
register int i,j,k,l;
register char dt;
register unsigned char* tmp = (unsigned char*)offset;
char mid_tmp[]; for(i=;i<;i++){
mid_tmp[i] = (tmp[i]<<(i)) | ((tmp[i+])>>(-i));
} memset(dist,,);
//进行置换
for(i=,l=;i<;i++){
for(dt =,j=;j>=;j--){
k = table_PC_2[l++]-;
dt = dt|(( (*(mid_tmp+(k>>)) >>( - k&0x07 ))&0x01 )<<j);
if(j==)
break;
}
dist[i] = dt;
}
} /**********************************************/ /**********************************************/
//加密过程 //初始置换 ip
//从offset位置开始将数据置换到 data[8-15]字节 ,然后重新复制到data[0-7]中
void fun_initReplacement(const char *offset){
register int i,j,l;
register unsigned char k,*tmp,*to;
//将数据块区域重置为 0
tmp = (unsigned char*)offset;
to = (unsigned char* )(data+);
memset(to,,);
for(i=,l=;i<;i++){
for(j=;j>=;j--){
k = table_IP[l++]-;
to[i] = to[i] | ((( *(tmp+(k>>))>>(- (k &0x07)))&0x01)<<j);
if(j==)
break;
}
}
memcpy(data,data+,);
//初始化指针
data_left = data;
data_right = data+;
} //末置换 fp
void fun_finalReplacement(){
//数据块存在 data[0]-data[7]中 !
//置换临时空间 data[8]-data[15]
register int i,j,l;
register unsigned char k,*tmp,*to;
//将数据块区域重置为 0
tmp = (unsigned char*)data;
to = (unsigned char*)(data+);
for(i=,l=;i<;i++){
for(j=;j>=;j--){
k = table_FP[l++]-;
to[i] = to[i] | ((( *(tmp+(k>>))>>(- (k &0x07)))&0x01)<<j);
if(j==)
break;
}
}
memcpy(data,to,); } //扩展置换
void fun_expandReplacement_32To48(){
//////////将右边的数据扩展至 48 位 !
register int i,j;
register unsigned char k,l,*tmp,*to_pos;
tmp = (unsigned char *)data_right;
to_pos = (unsigned char*)(data+);
memset(to_pos,,);
//printf("\n---------- 扩展置换 ---------\n");
for(i=,l=;i<;i++){
for(j= ,k=;j>=;j--){
k = table_E[l++]-;
*to_pos = (*to_pos)| (((*(tmp+(k>>)) >>( - (k&0x07) ))&0x01)<<j);
//printf("%d %d %x \n",l,k,((*(tmp+(k>>3)) >>(7 - (k&0x07) ))&0x01));
if(j==)
break;
}
to_pos++;
}
} //加 密钥 异或
void fun_xor_48(char *ktmp){
register int i;
char *dtmp = data+;
for(i=;i<;i++){
dtmp[i] = dtmp[i]^ktmp[i]; }
} // s盒置换
void fun_S_Replacement(){
// s盒工作原理 : 48位 分成8组.每组6位 0位和5位组成行定位, 1-4位组成列定位.
// 定位出来的数据即为替换后的 4 位数据
register unsigned char row,col,ctmp,index,i;
register char *dtmp;
static char tmp[];
dtmp = data+;
memset(tmp,,);
//((*(tmp+(k>>3)) >>(7 - (k&0x07) ))&0x01)
for(index =,ctmp=,i=;i< ;i++){
// row 为:index 接下来第零位和第五位
row = (((*(dtmp+((index)>>))>>((-((index)&0x07))))&0x01)<<); //第0位
row|=(((*(dtmp+((index+)>>))>>((-((index+)&0x07))))&0x01))&0x03;//第5位 col =(((*(dtmp+((index+)>>))>>((-((index+)&0x07))))&0x01)<<); //第1位
col|= (((*(dtmp+((index+)>>))>>((-((index+)&0x07))))&0x01)<<); //第2位
col|= (((*(dtmp+((index+)>>))>>((-((index+)&0x07))))&0x01)<<); //第3位
col|= (((*(dtmp+((index+)>>))>>((-((index+)&0x07))))&0x01))&0x0f;//第4位
ctmp = table_S[i][(row<<)+col]; //写入4位
tmp[i>>] = tmp[i>>] | ((ctmp&0xf)<<(((~i)&0x01)<<));
index+=;
}
memcpy(data+,tmp,);
} //P盒置换
void fun_P_Replacement(){
register unsigned char i,k,l;
static char tmp[],j;
register char *offset =data + ;
memset(tmp,,);
for(i=,l=;i<;i++){
for(k=,j=;j>=;j--){
k = table_P[l++]-;
tmp[i] = tmp[i] |((( * (offset+(k>>)))>>( - (k&0x07))&0x01)<<j);
if(j==)
break;
}
}
memcpy(data+,tmp,);
} //左右域异或
void fun_xor_32(){
register char i;
for(i=;i<;i++){
data_left[i] = data_left[i]^data[+i];
}
} //设置 密码 <生成过程所有密码>
void setKey(const char key[]){
register int i;
register char*offset,*to,*ct;
memcpy(keys[],key,);
fun_InitReplacementKey();
offset = keys[];
to = keys[];
ct = key_48[];
//16轮迭代算出需要的 <key>
for(i=;i<;i++){
fun_MoveKey(table_move[i],offset,to);
fun_ReplacementCompressKey(to,ct);
offset = to;
ct+=;
to+=;
}
} //加密
char* des(const char datas[]){
int i=;
static char *swapeTmp;
fun_initReplacement(datas);
for(i=;i<;i++){
fun_expandReplacement_32To48();
fun_xor_48(key_48[i]);
fun_S_Replacement();
fun_P_Replacement();
fun_xor_32();
swapeTmp = data_left;
data_left =data_right;
data_right =swapeTmp;
}//经检验前 15 轮可以正确运算...
{//第16轮
fun_expandReplacement_32To48();
fun_xor_48(key_48[i]);
fun_S_Replacement();
fun_P_Replacement();
fun_xor_32();
//printf("\n---- 16 轮-----\nData: %x Left: %x Right: %x ",data,data_left,data_right);
//现在状况是 data<right,left>需要将 left 和right的数据块调换过来!!!!!!
memcpy(data+,data,);
memcpy(data,data+,);
memcpy(data+,data+,);
memset(data+,,);
}
//末置换!
fun_finalReplacement();
return data;
} //解密算法
char * dedes(const char datas[]){
int i=;
static char *swapeTmp;
fun_initReplacement(datas);
for(i=;i>;i--){
fun_expandReplacement_32To48();
fun_xor_48(key_48[i]);
fun_S_Replacement();
fun_P_Replacement();
fun_xor_32();
swapeTmp = data_left;
data_left =data_right;
data_right =swapeTmp;
}//经检验前 15 轮可以正确运算...
{//第16轮
fun_expandReplacement_32To48();
fun_xor_48(key_48[i]);
fun_S_Replacement();
fun_P_Replacement();
fun_xor_32();
//现在状况是 data<right,left>需要将 left 和right的数据块调换过来!!!!!!
memcpy(data+,data,);
memcpy(data,data+,);
memcpy(data+,data+,);
memset(data+,,);
}
//末置换!
fun_finalReplacement();
data[]='\0';
return data;
}