头文件: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. Perl 哈希

    Perl 哈希 哈希是 key/value 对的集合. Perl中哈希变量以百分号 (%) 标记开始. 访问哈希元素格式:${key}. 以下是一个简单的哈希实例: 实例 #!/usr/bin/per ...

  2. luoguP1415 拆分数列 [dp]

    题目描述 给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数.如果有多组解,则输出使得最后一个数最小的同时,字典序最大的解(即先要满足最后一个数最小:如果有多组解,则使得第一个数尽量大:如 ...

  3. Spring-Security (学习记录三)--读取数据库中的用户和角色

    目录 1.先将hibernate的环境整合进来 2.创建一个数据库security,执行security.sql 3.修改spring-security.xml,采用数据库的方式读取用户跟角色 4.u ...

  4. Qt5编译使用QFtp

    使用 QNetworkAccessManager 可以实现 Ftp 的上传/下载功能(参考:Qt之FTP上传/下载),但有些原本 QFtp 有的功能 QNetworkAccessManager 却没有 ...

  5. 简述MapReduce数据流

    目前it基本都是一个套路,获得数据然后进行逻辑处理,存储数据. 基本上弄清楚整个的数据流向就等于把握了命脉. 现在说说mapreduce的数据流 1.首先数据会按照TextInputFormat按照特 ...

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

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

  7. python中字典排序

    一.Python的排序 1.reversed() 这个很好理解,reversed英文意思就是:adj. 颠倒的:相反的:(判决等)撤销的 print list(reversed(['dream','a ...

  8. Merge k Sorted Arrays【合并k个有序数组】【优先队列】

    Given k sorted integer arrays, merge them into one sorted array. Example Given 3 sorted arrays: [ [1 ...

  9. 数组模拟stack

    package com.cxy.springdataredis.data; import java.util.Scanner; public class StackDemo { public stat ...

  10. ES6 学习 -- Class继承

    (1)如何继承Class可以通过extends关键字实现继承,如下:class Father { } class Child extends Father { }// 这里子类Child继承父类Fat ...