Des算法的实现

  之所以会来写这个,是觉得自己前一段时间一直在找关于DES加密算法的资料,确实有很多代码,但是不同代码得出的结果都不一样。这我就不能忍了,最后还是决定自己去写一份代码。然后就有了现在这个代码。

    其实DES算法理解起来不难的,流程多看几遍也就理解了,要注意的是几个int数组一定不能有数据出错,我就是这么被坑了。。。。

  找资料的时候有一张图,一直受用,很清晰介绍DES加密的算法:





  废话不多说,下面上代码,我是用makefile管理和编译代码,所以文件分得会细一点,读者可以把几个.c文件都放到一个.c文件中,这样就可以实现单文件了。(用一个文件 可以跳过makefile的部分)

  文件结构如下图:




    首先是makefile文件。

main:main.o changeStr.o round.o doDes.o
	cc -g -o $@ $^
main.o:main.c
	cc -g -c $<
changeStr.o:changeStr.c
	cc -g -c $<
round.o:round.c
	cc -g -c $<
doDes.o:doDes.c
	cc -g -c $<

clean:
	rm -f main\
	rm -f main.exe\
	rm *.o
  main主函数如下:其中包含了三个测试的函数,分别对应单DES加解密,3DES双倍长和三倍长加解密。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "def.h"

void doFflushWithC()
{
  char ch;
  while ( (ch = getchar()) != '\n' && ch != EOF ) ;   /* 通过 while 循环把输入流中的余留数据“吃”掉 */ 

  //fflush(stdin);标准库里面没有定义,所以没有效果,
  //使用 scanf("%*[^\n]"); 也可以清空输入流,不过会残留 \n 字符。  */   
}

void test_single()
{
  char  in_data[17]={'\0'};     //存放用户输入的明文    
  char  key_data[17]={'\0'};         //存放用户输入的密码
  char  out_data[17]={'\0'},out_data2[17]={'\0'};    //存放得出的加密密文

  //模拟数据输入
  memcpy(in_data,"a406753854abcdef",16);
  memcpy(key_data,"a34457799bbcdff1",16);

  //单DES加密产生密文
  doSingleDes(in_data, key_data, out_data, 1);           //加密密文
  doSingleDes(out_data, key_data, out_data2, 0);         //解密密文

  printf("加密前的明文:%s\n",in_data);
  printf("加密用的密钥:%s\n",key_data);
  printf("加密后的密文:%s\n",out_data);
  printf("解密后的明文:%s\n",out_data2);
}
void test_double()
{
  char  in_data[17]={'\0'};     //存放用户输入的明文    
  char  key_data[33]={'\0'};         //存放用户输入的密码
  char  out_data[17]={'\0'},out_data2[17]={'\0'};    //存放得出的加密密文

  //模拟数据输入
  memcpy(in_data,"a406753854abcdef",16);
  memcpy(key_data,"a34457799bbcdff10102030405060708",32);

  //单DES加密产生密文
  doDoubleDes(in_data, key_data, out_data, 1);           //加密密文
  doDoubleDes(out_data, key_data, out_data2, 0);         //解密密文

  printf("加密前的明文:%s\n",in_data);
  printf("加密用的密钥:%s\n",key_data);
  printf("加密后的密文:%s\n",out_data);
  printf("解密后的明文:%s\n",out_data2);
}

void test_triple()
{
  char  in_data[17]={'\0'};     //存放用户输入的明文    
  char  key_data[49]={'\0'};         //存放用户输入的密码
  char  out_data[17]={'\0'},out_data2[17]={'\0'};    //存放得出的加密密文

  //模拟数据输入
  memcpy(in_data,"a406753854abcdef",16);
  memcpy(key_data,"a34457799bbcdff101020304050607089092939495969798",48);

  //单DES加密产生密文
  doTripleDes(in_data, key_data, out_data, 1);           //加密密文
  doTripleDes(out_data, key_data, out_data2, 0);         //解密密文

  printf("加密前的明文:%s\n",in_data);
  printf("加密用的密钥:%s\n",key_data);
  printf("加密后的密文:%s\n",out_data);
  printf("解密后的明文:%s\n",out_data2);
}


int main()
{
    test_triple();
    return 0;
}
    头文件定义了一些函数:

  

#ifndef _DEF_H_
#define _DEF_H_


#define PRINT_LOG	0

//字符及字符串转换类函数,changeStr.c中定义
int 	changeAscToInt(char ch);		//十六进制ASC码转换成Int类型,'2'->2,'A'->10
char 	changeIntToAsc(int a);		//十进制转换成字符2>"02",10->"8F"
int 	changeStrAscToHex(char *asc,char *hex,int len);	//"ABC123"-->0xABC123,压缩成半长
int		changeStrHexToAsc(char *hex,char *asc,int len);	//0xABC123-->"ABC123",扩展成双倍长
int 	changeIntToIntArray(int *to, int begin, int len, int n) ;//将一个int转换成n个二进制存入to数组中	
void 	changeHexStrToIntArray(char *hex, int *in, int len);//将len长的十六进制字符串,转换并存入int数组中	
void 	changeIntArrayToHexStr(int *in, char *hex, int len);	//将int数组中转换存储到十六进制字符串hex中
void 	print_intArraybyHex(char *title,int *in,int len);	//将int数组按十六进制来打印显示


//转换函数,round.c中定义
void 	exchange(int *from, int *to, const int *rule,int n);//按转换表及长度转换数组到别一个数组
void 	xorInt(int *to, int *comp,int len);					//int类型的异或函数
void 	key28MoveByTimes(int key[56], int times);			//密钥16次循环中左移函数

//DES加密的接口函数,在doDes.c中定义,doDesType=1时为加密,其他值时为解密
void 	doSingleDes(char* in_data, char*key_data, char *out_data, int doDesType);	//单倍长的DES加/解密
void  	doDoubleDes(char* in_data, char*key_data, char *out_data, int doDesType);	//双倍长双DES加/解密

//标准输入操作,main.c函数中定义
void 	doFflushWithC();						//C语言中实现fflush()清空标准输入缓冲区的实现
int 	inputAscStrToHex(char *hex,int len);	//输入len
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值