头文件: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. hibernate(一对多关系)

    代码   public class Main { public static void main(String[] args) { SessionFactory sty = HibernateUtil ...

  2. Delphi 一些pas

    Delphi -- 创建 桌面.发送到....快速启动栏.开始菜单.程序菜单.右键菜 单 {====================================================== ...

  3. NX二次开发-UFUN输出UF函数使用错误UF_get_fail_message

    #include <uf.h> #include <uf_ui.h> #include <uf_modl.h> UF_initialize(); UF_FEATUR ...

  4. NX二次开发-NXOPEN设置工程图表格注释字体workPart->Fonts()->AddFont("chinesef_fs", NXOpen::FontCollection::TypeNx);

    NX9+VS2012 #include <uf.h> #include <uf_tabnot.h> #include <NXOpen/Part.hxx> #incl ...

  5. Java-Class-C:org.springframework.http.ResponseEntity

    ylbtech-Java-Class-C:org.springframework.http.ResponseEntity 1.返回顶部 1. org.springframework.http Clas ...

  6. 3.7.4 Tri0 and tri1 nets

    Frm: IEEE Std 1364™-2001, IEEE Standard Verilog® Hardware Description Language The tri0 and tri1 net ...

  7. EasyMock添加行为

    EasyMock使用expect()方法或expectLassCall()方法添加一个功能,一个模拟对象.请看下面的代码片段. 1 //add the behavior of calc service ...

  8. 如何提高阿里云cdn命中率?原命中率极低。

    博客搬迁了,给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/08/29/%E5%A6%82%E4%BD%95%E6%8F%90%E9%AB%98%E9 ...

  9. 来个我一起学习Python把!!!(新手共同努力)

    <初识Python> 大家好,让我们一起来学习Python,因本人也是个新手但我会把我所学的东西分享出来,并记录自己的经验学习过程,不单单是分享代码,会详细的讲解,如有错误地方希望大家指点 ...

  10. 【csp】2017-9

    1.打酱油 题目: 题意:如上. 题解:经典问题.看代码吧.qwq 代码: #include<iostream> #include<cstdio> #include<al ...