头文件:DES.h

 #ifndef DES_hpp
#define DES_hpp #include <stdio.h>
#include <memory.h>
#include <time.h>
#include <stdlib.h> #define PLAIN_FILE_OPEN_ERROR -1
#define KEY_FILE_OPEN_ERROR -2
#define CIPHER_FILE_OPEN_ERROR -3
#define OK 1 typedef char ElemType; int ByteToBit(ElemType ch,ElemType bit[]);
int BitToByte(ElemType bit[],ElemType *ch);
int Char8ToBit64(ElemType ch[],ElemType bit[]);
int Bit64ToChar8(ElemType bit[],ElemType ch[]);
int DES_MakeSubKeys(ElemType key[],ElemType subKeys[][]);
int DES_PC1_Transform(ElemType key[], ElemType tempbts[]);
int DES_PC2_Transform(ElemType key[], ElemType tempbts[]);
int DES_ROL(ElemType data[], int time);
int DES_IP_Transform(ElemType data[]);
int DES_IP_1_Transform(ElemType data[]);
int DES_E_Transform(ElemType data[]);
int DES_P_Transform(ElemType data[]);
int DES_SBOX(ElemType data[]);
int DES_XOR(ElemType R[], ElemType L[],int count);
int DES_Swap(ElemType left[],ElemType right[]);
int DES_EncryptBlock(ElemType plainBlock[], ElemType subKeys[][], ElemType cipherBlock[]);
int DES_DecryptBlock(ElemType cipherBlock[], ElemType subKeys[][], ElemType plainBlock[]);
int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile);
int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile); #endif /* DES_hpp */

C代码:DES.cpp

 #include "DES.h"

 //初始置换表IP
int IP_Table[] = { ,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,};
//逆初始置换表IP^-1
int IP_1_Table[] = {,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,}; //扩充置换表E
int E_Table[] = {, , , , , ,
, , , , , ,
, ,,,,,
,,,,,,
,,,,,,
,,,,,,
,,,,,,
,,,,, }; //置换函数P
int P_Table[] = {,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,}; //S盒
int S[][][] =//S1
{{{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}},
//S2
{{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}},
//S3
{{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}},
//S4
{{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}},
//S5
{{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}},
//S6
{{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}},
//S7
{{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}},
//S8
{{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,},
{,,,,,,,,,,,,,,,}}};
//置换选择1
int PC_1[] = {,,,,,,,
,,,,,,,
,,,,,,,
,,,,,,,
,,,,,,,
,,,,,,,
,,,,,,,
,,,,,,}; //置换选择2
int PC_2[] = {,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,,}; //对左移次数的规定
int MOVE_TIMES[] = {,,,,,,,,,,,,,,,}; //字节转换成二进制
int ByteToBit(ElemType ch, ElemType bit[]){
int cnt;
for(cnt = ;cnt < ; cnt++){
*(bit+cnt) = (ch>>cnt)&;
}
return ;
} //二进制转换成字节
int BitToByte(ElemType bit[],ElemType *ch){
int cnt;
for(cnt = ;cnt < ; cnt++){
*ch |= *(bit + cnt)<<cnt;
}
return ;
} //将长度为8的字符串转为二进制位串
int Char8ToBit64(ElemType ch[],ElemType bit[]){
int cnt;
for(cnt = ; cnt < ; cnt++){
ByteToBit(*(ch+cnt),bit+(cnt<<));
}
return ;
} //将二进制位串转为长度为8的字符串
int Bit64ToChar8(ElemType bit[],ElemType ch[]){
int cnt;
memset(ch,,);
for(cnt = ; cnt < ; cnt++){
BitToByte(bit+(cnt<<),ch+cnt);
}
return ;
} //生成子密钥
int DES_MakeSubKeys(ElemType key[],ElemType subKeys[][]){
ElemType temp[];
int cnt;
DES_PC1_Transform(key,temp);//PC1置换
for(cnt = ; cnt < ; cnt++){//16轮跌代,产生16个子密钥
DES_ROL(temp,MOVE_TIMES[cnt]);//循环左移
DES_PC2_Transform(temp,subKeys[cnt]);//PC2置换,产生子密钥
}
return ;
} //密钥置换1
int DES_PC1_Transform(ElemType key[], ElemType tempbts[]){
int cnt;
for(cnt = ; cnt < ; cnt++){
tempbts[cnt] = key[PC_1[cnt]];
}
return ;
} //密钥置换2
int DES_PC2_Transform(ElemType key[], ElemType tempbts[]){
int cnt;
for(cnt = ; cnt < ; cnt++){
tempbts[cnt] = key[PC_2[cnt]];
}
return ;
} //循环左移
int DES_ROL(ElemType data[], int time){
ElemType temp[]; //保存将要循环移动到右边的位
memcpy(temp,data,time);
memcpy(temp+time,data+,time); //前28位移动
memcpy(data,data+time,-time);
memcpy(data+-time,temp,time); //后28位移动
memcpy(data+,data++time,-time);
memcpy(data+-time,temp+time,time); return ;
} //IP置换
int DES_IP_Transform(ElemType data[]){
int cnt;
ElemType temp[];
for(cnt = ; cnt < ; cnt++){
temp[cnt] = data[IP_Table[cnt]];
}
memcpy(data,temp,);
return ;
} //IP逆置换
int DES_IP_1_Transform(ElemType data[]){
int cnt;
ElemType temp[];
for(cnt = ; cnt < ; cnt++){
temp[cnt] = data[IP_1_Table[cnt]];
}
memcpy(data,temp,);
return ;
} //扩展置换
int DES_E_Transform(ElemType data[]){
int cnt;
ElemType temp[];
for(cnt = ; cnt < ; cnt++){
temp[cnt] = data[E_Table[cnt]];
}
memcpy(data,temp,);
return ;
} //P置换
int DES_P_Transform(ElemType data[]){
int cnt;
ElemType temp[];
for(cnt = ; cnt < ; cnt++){
temp[cnt] = data[P_Table[cnt]];
}
memcpy(data,temp,);
return ;
} //异或
int DES_XOR(ElemType R[], ElemType L[] ,int count){
int cnt;
for(cnt = ; cnt < count; cnt++){
R[cnt] ^= L[cnt];
}
return ;
} //S盒置换
int DES_SBOX(ElemType data[]){
int cnt;
int line,row,output;
int cur1,cur2;
for(cnt = ; cnt < ; cnt++){
cur1 = cnt*;
cur2 = cnt<<; //计算在S盒中的行与列
line = (data[cur1]<<) + data[cur1+];
row = (data[cur1+]<<) + (data[cur1+]<<)
+ (data[cur1+]<<) + data[cur1+];
output = S[cnt][line][row]; //化为2进制
data[cur2] = (output&0X08)>>;
data[cur2+] = (output&0X04)>>;
data[cur2+] = (output&0X02)>>;
data[cur2+] = output&0x01;
}
return ;
} //交换
int DES_Swap(ElemType left[], ElemType right[]){
ElemType temp[];
memcpy(temp,left,);
memcpy(left,right,);
memcpy(right,temp,);
return ;
} //加密单个分组
int DES_EncryptBlock(ElemType plainBlock[], ElemType subKeys[][], ElemType cipherBlock[]){
ElemType plainBits[];
ElemType copyRight[];
int cnt; Char8ToBit64(plainBlock,plainBits);
//初始置换(IP置换)
DES_IP_Transform(plainBits); //16轮迭代
for(cnt = ; cnt < ; cnt++){
memcpy(copyRight,plainBits+,);
//将右半部分进行扩展置换,从32位扩展到48位
DES_E_Transform(copyRight);
//将右半部分与子密钥进行异或操作
DES_XOR(copyRight,subKeys[cnt],);
//异或结果进入S盒,输出32位结果
DES_SBOX(copyRight);
//P置换
DES_P_Transform(copyRight);
//将明文左半部分与右半部分进行异或
DES_XOR(plainBits,copyRight,);
if(cnt != ){
//最终完成左右部的交换
DES_Swap(plainBits,plainBits+);
}
}
//逆初始置换(IP^1置换)
DES_IP_1_Transform(plainBits);
Bit64ToChar8(plainBits,cipherBlock);
return ;
} //解密单个分组
int DES_DecryptBlock(ElemType cipherBlock[], ElemType subKeys[][],ElemType plainBlock[]){
ElemType cipherBits[];
ElemType copyRight[];
int cnt; Char8ToBit64(cipherBlock,cipherBits);
//初始置换(IP置换)
DES_IP_Transform(cipherBits); //16轮迭代
for(cnt = ; cnt >= ; cnt--){
memcpy(copyRight,cipherBits+,);
//将右半部分进行扩展置换,从32位扩展到48位
DES_E_Transform(copyRight);
//将右半部分与子密钥进行异或操作
DES_XOR(copyRight,subKeys[cnt],);
//异或结果进入S盒,输出32位结果
DES_SBOX(copyRight);
//P置换
DES_P_Transform(copyRight);
//将明文左半部分与右半部分进行异或
DES_XOR(cipherBits,copyRight,);
if(cnt != ){
//最终完成左右部的交换
DES_Swap(cipherBits,cipherBits+);
}
}
//逆初始置换(IP^1置换)
DES_IP_1_Transform(cipherBits);
Bit64ToChar8(cipherBits,plainBlock);
return ;
} //加密文件
int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile){
FILE *plain,*cipher;
int count;
ElemType plainBlock[],cipherBlock[],keyBlock[];
ElemType bKey[];
ElemType subKeys[][];
if((plain = fopen(plainFile,"rb")) == NULL){
return PLAIN_FILE_OPEN_ERROR;
}
if((cipher = fopen(cipherFile,"wb")) == NULL){
return CIPHER_FILE_OPEN_ERROR;
}
//设置密钥
memcpy(keyBlock,keyStr,);
//将密钥转换为二进制流
Char8ToBit64(keyBlock,bKey);
//生成子密钥
DES_MakeSubKeys(bKey,subKeys);
while(!feof(plain)){
//每次读8个字节,并返回成功读取的字节数
if((count = fread(plainBlock,sizeof(char),,plain)) == ){
DES_EncryptBlock(plainBlock,subKeys,cipherBlock);
fwrite(cipherBlock,sizeof(char),,cipher);
}
}
if(count){
//填充
memset(plainBlock + count,'\0', - count);
//最后一个字符保存包括最后一个字符在内的所填充的字符数量
plainBlock[] = - count;
DES_EncryptBlock(plainBlock,subKeys,cipherBlock);
fwrite(cipherBlock,sizeof(char),,cipher);
}
fclose(plain);
fclose(cipher);
return OK;
} //解密文件
int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile){
FILE *plain, *cipher;
int count,times = ;
long fileLen;
ElemType plainBlock[],cipherBlock[],keyBlock[];
ElemType bKey[];
ElemType subKeys[][];
if((cipher = fopen(cipherFile,"rb")) == NULL){
return CIPHER_FILE_OPEN_ERROR;
}
if((plain = fopen(plainFile,"wb")) == NULL){
return PLAIN_FILE_OPEN_ERROR;
} //设置密钥
memcpy(keyBlock,keyStr,);
//将密钥转换为二进制流
Char8ToBit64(keyBlock,bKey);
//生成子密钥
DES_MakeSubKeys(bKey,subKeys); //取文件长度
fseek(cipher,,SEEK_END); //将文件指针置尾
fileLen = ftell(cipher); //取文件指针当前位置
rewind(cipher); //将文件指针重指向文件头
while(){
//密文的字节数一定是8的整数倍
fread(cipherBlock,sizeof(char),,cipher);
DES_DecryptBlock(cipherBlock,subKeys,plainBlock);
times += ;
if(times < fileLen){
fwrite(plainBlock,sizeof(char),,plain);
}
else{
break;
}
}
//判断末尾是否被填充
if(plainBlock[] < ){
for(count = - plainBlock[]; count < ; count++){
if(plainBlock[count] != '\0'){
break;
}
}
}
if(count == ){//有填充
fwrite(plainBlock,sizeof(char), - plainBlock[],plain);
}
else{//无填充
fwrite(plainBlock,sizeof(char),,plain);
} fclose(plain);
fclose(cipher);
return OK;
}

main.cpp

 #include <iostream>

 #include "DES.h"

 int main(int argc, const char * argv[]) {
// insert code here...
std::cout << "CrypDes Start!\n";
std::cout << "加密文件:res/test_origin.png\n";
DES_Encrypt("res/test_origin.png","kkkkkkkk","res/test_encrypt.png");
std::cout << "输出加密文件:res/test_encrypt.png\n";
std::cout << "解密文件:res/test_encrypt.png\n";
DES_Decrypt("res/test_encrypt.png","kkkkkkkk","res/test_decrypt.png");
std::cout << "输出加密文件:res/test_decrypt.png\n";
return ;
}

输出:

DES加密算法-C语言的更多相关文章

  1. DES和3DES加密算法C语言实现【转】

    转自:https://blog.csdn.net/leumber/article/details/78043675 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...

  2. Atitit.加密算法 des  aes 各个语言不同的原理与解决方案java php c#

    Atitit.加密算法 des  aes 各个语言不同的原理与解决方案java php c# 1. 加密算法的参数::算法/模式/填充 1 2. 标准加密api使用流程1 2.1. Md5——16bi ...

  3. 在.NET Core 里使用 BouncyCastle 的DES加密算法

    .NET Core上面的DES等加密算法要等到1.2 才支持,我们可是急需这个算法的支持,文章<使用 JavaScriptService 在.NET Core 里实现DES加密算法>需要用 ...

  4. 浅谈DES加密算法

    一.DES加密算法介绍 1.要求密钥必须是8个字节,即64bit长度 2.因为密钥是byte[8] , 代表字符串也可以是非可见的字节,可以与Base64编码算法一起使用 3.加密.解密都需要通过字节 ...

  5. JAVA使用DES加密算法加密解密

    程序中使用了.properties文件作为参数配置文档,好处是灵活配置各项参数 一旦对数据库的一些参数进行了配置,势必涉及数据库的IP,端口,用户名和密码 properties文件全是unicode编 ...

  6. md5加密算法c语言版

    from: http://blog.sina.com.cn/s/blog_693de6100101kcu6.html 注:以下是md5加密算法c语言版(16/32位) ---------------- ...

  7. 对称密码——DES加密算法

    前言 本篇博文将介绍对称密码算法中的DES密码的算法原理与代码实现(Java) DES算法原理 DES加密算法是对称加密算法(加密和解密使用同一个密钥)中的一种,DES也是分组密码,以64位为分组对明 ...

  8. des加密算法java&c#

    项目中用到的数据加密方式是ECB模式的DES加密得到的十六进制字符串.技术支持让写一个.net版的加密算法.这里做一下记录. java版: 16进制使用的是bouncycastle. import c ...

  9. android和.net webservice中的DES加密算法

    也是看了一堆的例子,本身并不会写加密算法,好在只要会用就行了,我们把在app中使用的参数加密,然后在.net端的webservice中进行解密,本身并没有什么问题,但是android下和.net下的d ...

随机推荐

  1. 大转盘抽奖css3+js(简单书写)

    今天花了一段时间简单写了下抽奖大转盘,这里写的只是自己想到的简单的写了下(也希望收获其他想法),后续,再写的话会更新. 大体思路:页面加载完成后,通过监听开始按钮的点击事件.然后会根据产生的随机数,通 ...

  2. NX二次开发-UFUN圆弧矩阵标记、起始角和结束角(弧度测量)、圆弧中心坐标和圆弧半径UF_CURVE_ask_arc_data(边可以用)

    1 NX11+VS2013 2 3 #include <uf.h> 4 #include <uf_ui.h> 5 #include <uf_modl.h> 6 #i ...

  3. shell 单引号&双引号的使用

    使用双引号: shell> X='parameter' shell> echo "Hello $X" Hello parameter 单引号中嵌套单引号: shell& ...

  4. 2018北京网络赛 G The Mole /// 分块暴力 点线距离

    题目大意: 给定n段线段 编号为1~n 接下来m个询问 给定一点 输出离该点最近的线段的最小编号(距离相等时取编号小的) 题解 大致就是 1.坐标范围为(0,2^16-1) 将坐标系划分为2^8*2^ ...

  5. PE头里的东西更多。。。越看越恶心了,我都不想看了

    winnt.h 中,定义的PE头结构体 typedef struct _IMAGE_NT_HEADERS{DWORD Signature;//PE文件头标志:PE\0\0.在开始DOS header的 ...

  6. 使用雪碧图Css Sprite精灵 | 加速网页响应速度

    什么是CSS Sprite精灵? 是用于前端的一种图片应用技术,通常情况,我们的开发的网页或许有很多张图片,假如在一个页面上有50多张小图片,这意味着浏览器要逐个下载50张图片.Css Sprite它 ...

  7. 基于第三方开源库的OPC服务器开发指南(3)——OPC客户端

    本篇将讲解如何编写一个OPC客户端程序测试我们在前文<基于第三方开源库的OPC服务器开发指南(2)——LightOPC的编译及部署>一篇建立的服务器.本指南的目的是熟悉OPC服务器的开发流 ...

  8. JS函数 编程练习 使用javascript代码写出一个函数:实现传入两个整数后弹出较大的整数。

    编程练习 使用javascript代码写出一个函数:实现传入两个整数后弹出较大的整数. 任务 第一步: 编写代码完成一个函数的定义吧. 第二步: 我们来补充函数体中的控制语句,完成函数功能吧. 提示: ...

  9. 【CSP-S/J 2019】初赛注意事项

    UPD:10-25-13:33 正式成绩出了,省里500多名应该进了吧... UPD:10-20-10:07 现在又很慌啊,怎么感觉82又一点都不稳啊... 然后现在又不太想写文化课作业...我是不是 ...

  10. AM8互联设置方法

    Am8互联设置 这个只需要部署在一个总部的AM8的 Oiorg所在机器上就可以 环境: Windows 2012 or windows 2008,IIS ,.Net4 AM8 数据库必须升级到:201 ...