头文件: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. bzoj1057: [ZJOI2007]棋盘制作 [dp][单调栈]

    Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应 ...

  2. nginx中reuqest_uri与uri的区别说明

    reuqest_uri:即客户端发送来的原生请求URI,包括请求参数 uri:请求URI,不包括任何请求参数 举例说明: 1.比如客户端以 get 方式请求 /admin 页面,并且带 id 和 na ...

  3. jquery preventDefault()事件

    定义和用法 preventDefault() 方法阻止元素发生默认的行为(例如,当点击提交按钮时阻止对表单的提交). 语法 event.preventDefault() 参数 描述 event 必需. ...

  4. ubuntu 12.04系统黑屏,登录界面黑屏

    ubuntu 12.04系统黑屏,登录界面黑屏 原文链接:http://www.2cto.com/os/201305/213737.html   1.硬件环境     Intel® Core™ i5- ...

  5. linux下使用scp在服务器之间拷贝文件 (转载)

    CentOS, 本地服务器,ip: 192.168.1.111Ubuntu, 远程服务器,ip: 192.168.1.112 1.拷贝远程服务器的目录到本地服务器远程服务器192.168.1.112上 ...

  6. USACO2008 Cow Cars /// oj23323

    题目大意: N (1 ≤ N ≤ 50,000)头牛被编号为1-N,牛i可以在M(1 ≤ M ≤ N)条不同的高速路上以Si (1 ≤ Si ≤ 1,000,000) km/h的速度飞驰 为了避免相撞 ...

  7. React和vue的差异和相似地方

    React 单向绑定(加插件后,还是可以双向绑定) Vue 双向绑定 组件化 1. React,需要编写render函数, 2. 当React状态的状态state改变是render就会重新被调用, 重 ...

  8. 【笔记篇】斜率优化dp(五) USACO08MAR土地购(征)买(用)Land Acquisition

    好好的题目连个名字都不统一.. 看到这种最大最小的就先排个序嘛= =以x为第一关键字, y为第二关键字排序. 然后有一些\(x_i<=x_{i+1},且y_i<=y_{i+1}\)的土地就 ...

  9. Windows shutdown

    用法: shutdown [/i | /l | /s | /sg | /r | /g | /a | /p | /h | /e | /o] [/hybrid] [/soft] [/fw] [/f]    ...

  10. 常用Oracle操作语句

    --常用的字段类型有:varchar2,char,nchar,date,long,number,float,BLOB,CLOB --添加表字段 ); --修改表字段 ); --删除表字段 alter ...