原文转自 http://www.cnblogs.com/imapla/archive/2012/09/07/2674788.html

用C语言实现DES(数据加密算法)的一个例子,密文和密钥都是8个字符。

1、VC6 Win32 Console Application

/*-------------------------------------------------------
Data Encryption Standard 56位密钥加密64位数据
2011.10
--------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include "bool.h" // 位处理
#include "tables.h" void BitsCopy(bool *DatOut,bool *DatIn,int Len); // 数组复制 void ByteToBit(bool *DatOut,char *DatIn,int Num); // 字节到位
void BitToByte(char *DatOut,bool *DatIn,int Num); // 位到字节 void BitToHex(char *DatOut,bool *DatIn,int Num); // 二进制到十六进制 64位 to 4*16字符
void HexToBit(bool *DatOut,char *DatIn,int Num); // 十六进制到二进制 void TablePermute(bool *DatOut,bool *DatIn,const char *Table,int Num); // 位表置换函数
void LoopMove(bool *DatIn,int Len,int Num); // 循环左移 Len长度 Num移动位数
void Xor(bool *DatA,bool *DatB,int Num); // 异或函数 void S_Change(bool DatOut[],bool DatIn[]); // S盒变换
void F_Change(bool DatIn[],bool DatKi[]); // F函数 void SetKey(char KeyIn[]); // 设置密钥
void PlayDes(char MesOut[],char MesIn[]); // 执行DES加密
void KickDes(char MesOut[],char MesIn[]); // 执行DES解密 int main()
{
int i=;
char MesHex[]={}; // 16个字符数组用于存放 64位16进制的密文
char MyKey[]={}; // 初始密钥 8字节*8
char YourKey[]={}; // 输入的解密密钥 8字节*8
char MyMessage[]={}; // 初始明文 /*-----------------------------------------------*/ printf("Welcome! Please input your Message(64 bit):\n");
gets(MyMessage); // 明文
printf("Please input your Secret Key:\n");
gets(MyKey); // 密钥 while(MyKey[i]!='\0') // 计算密钥长度
{
i++;
} while(i!=) // 不是8 提示错误
{
printf("Please input a correct Secret Key!\n");
gets(MyKey);
i=;
while(MyKey[i]!='\0') // 再次检测
{
i++;
}
} SetKey(MyKey); // 设置密钥 得到子密钥Ki PlayDes(MesHex,MyMessage); // 执行DES加密 printf("Your Message is Encrypted!:\n"); // 信息已加密
for(i=;i<;i++)
{
printf("%c ",MesHex[i]);
}
printf("\n");
printf("\n"); printf("Please input your Secret Key to Deciphering:\n"); // 请输入密钥以解密
gets(YourKey); // 得到密钥
SetKey(YourKey); // 设置密钥 KickDes(MyMessage,MesHex); // 解密输出到MyMessage printf("Deciphering Over !!:\n"); // 解密结束
for(i=;i<;i++)
{
printf("%c ",MyMessage[i]);
}
printf("\n");
system("pause"); /*------------------------------------------------*/
} /*-------------------------------
把DatIn开始的长度位Len位的二进制
复制到DatOut后
--------------------------------*/
void BitsCopy(bool *DatOut,bool *DatIn,int Len) // 数组复制 OK
{
int i=;
for(i=;i<Len;i++)
{
DatOut[i]=DatIn[i];
}
} /*-------------------------------
字节转换成位函数
每8次换一个字节 每次向右移一位
和1与取最后一位 共64位
--------------------------------*/
void ByteToBit(bool *DatOut,char *DatIn,int Num) // OK
{
int i=;
for(i=;i<Num;i++)
{
DatOut[i]=(DatIn[i/]>>(i%))&0x01;
}
} /*-------------------------------
位转换成字节函数
字节数组每8次移一位
位每次向左移 与上一次或
---------------------------------*/
void BitToByte(char *DatOut,bool *DatIn,int Num) // OK
{
int i=;
for(i=;i<(Num/);i++)
{
DatOut[i]=;
}
for(i=;i<Num;i++)
{
DatOut[i/]|=DatIn[i]<<(i%);
}
} /*----------------------------------
二进制密文转换为十六进制
需要16个字符表示
-----------------------------------*/
void BitToHex(char *DatOut,bool *DatIn,int Num)
{
int i=;
for(i=;i<Num/;i++)
{
DatOut[i]=;
}
for(i=;i<Num/;i++)
{
DatOut[i] = DatIn[i*]+(DatIn[i*+]<<)
+(DatIn[i*+]<<)+(DatIn[i*+]<<);
if((DatOut[i]%)>)
{
DatOut[i]=DatOut[i]%+''; // 余数大于9时处理 10-15 to A-F
} // 输出字符
else
{
DatOut[i]=DatOut[i]%+''; // 输出字符
}
} } /*---------------------------------------------
十六进制字符转二进制
----------------------------------------------*/
void HexToBit(bool *DatOut,char *DatIn,int Num)
{
int i=; // 字符型输入
for(i=;i<Num;i++)
{
if((DatIn[i/])>'') // 大于9
{
DatOut[i]=((DatIn[i/]-'')>>(i%))&0x01;
}
else
{
DatOut[i]=((DatIn[i/]-'')>>(i%))&0x01;
}
}
} // 表置换函数 OK
void TablePermute(bool *DatOut,bool *DatIn,const char *Table,int Num)
{
int i=;
static bool Temp[]={};
for(i=;i<Num;i++) // Num为置换的长度
{
Temp[i]=DatIn[Table[i]-]; // 原来的数据按对应的表上的位置排列
}
BitsCopy(DatOut,Temp,Num); // 把缓存Temp的值输出
} // 子密钥的移位
void LoopMove(bool *DatIn,int Len,int Num) // 循环左移 Len数据长度 Num移动位数
{
static bool Temp[]={}; // 缓存 OK
BitsCopy(Temp,DatIn,Num); // 将数据最左边的Num位(被移出去的)存入Temp
BitsCopy(DatIn,DatIn+Num,Len-Num); // 将数据左边开始的第Num移入原来的空间
BitsCopy(DatIn+Len-Num,Temp,Num); // 将缓存中移出去的数据加到最右边
} // 按位异或
void Xor(bool *DatA,bool *DatB,int Num) // 异或函数
{
int i=;
for(i=;i<Num;i++)
{
DatA[i]=DatA[i]^DatB[i]; // 异或
}
} // 输入48位 输出32位 与Ri异或
void S_Change(bool DatOut[],bool DatIn[]) // S盒变换
{
int i,X,Y; // i为8个S盒
for(i=,Y=,X=;i<;i++,DatIn+=,DatOut+=) // 每执行一次,输入数据偏移6位
{ // 每执行一次,输出数据偏移4位
Y=(DatIn[]<<)+DatIn[]; // af代表第几行
X=(DatIn[]<<)+(DatIn[]<<)+(DatIn[]<<)+DatIn[]; // bcde代表第几列
ByteToBit(DatOut,&S_Box[i][Y][X],); // 把找到的点数据换为二进制
}
} // F函数
void F_Change(bool DatIn[],bool DatKi[]) // F函数
{
static bool MiR[]={}; // 输入32位通过E选位变为48位
TablePermute(MiR,DatIn,E_Table,);
Xor(MiR,DatKi,); // 和子密钥异或
S_Change(DatIn,MiR); // S盒变换
TablePermute(DatIn,DatIn,P_Table,); // P置换后输出
} void SetKey(char KeyIn[]) // 设置密钥 获取子密钥Ki
{
int i=;
static bool KeyBit[]={}; // 密钥二进制存储空间
static bool *KiL=&KeyBit[],*KiR=&KeyBit[]; // 前28,后28共56
ByteToBit(KeyBit,KeyIn,); // 把密钥转为二进制存入KeyBit
TablePermute(KeyBit,KeyBit,PC1_Table,); // PC1表置换 56次
for(i=;i<;i++)
{
LoopMove(KiL,,Move_Table[i]); // 前28位左移
LoopMove(KiR,,Move_Table[i]); // 后28位左移
TablePermute(SubKey[i],KeyBit,PC2_Table,);
// 二维数组 SubKey[i]为每一行起始地址
// 每移一次位进行PC2置换得 Ki 48位
}
} void PlayDes(char MesOut[],char MesIn[]) // 执行DES加密
{ // 字节输入 Bin运算 Hex输出
int i=;
static bool MesBit[]={}; // 明文二进制存储空间 64位
static bool Temp[]={};
static bool *MiL=&MesBit[],*MiR=&MesBit[]; // 前32位 后32位
ByteToBit(MesBit,MesIn,); // 把明文换成二进制存入MesBit
TablePermute(MesBit,MesBit,IP_Table,); // IP置换
for(i=;i<;i++) // 迭代16次
{
BitsCopy(Temp,MiR,); // 临时存储
F_Change(MiR,SubKey[i]); // F函数变换
Xor(MiR,MiL,); // 得到Ri
BitsCopy(MiL,Temp,); // 得到Li
}
TablePermute(MesBit,MesBit,IPR_Table,);
BitToHex(MesOut,MesBit,);
} void KickDes(char MesOut[],char MesIn[]) // 执行DES解密
{ // Hex输入 Bin运算 字节输出
int i=;
static bool MesBit[]={}; // 密文二进制存储空间 64位
static bool Temp[]={};
static bool *MiL=&MesBit[],*MiR=&MesBit[]; // 前32位 后32位
HexToBit(MesBit,MesIn,); // 把密文换成二进制存入MesBit
TablePermute(MesBit,MesBit,IP_Table,); // IP置换
for(i=;i>=;i--)
{
BitsCopy(Temp,MiL,);
F_Change(MiL,SubKey[i]);
Xor(MiL,MiR,);
BitsCopy(MiR,Temp,);
}
TablePermute(MesBit,MesBit,IPR_Table,);
BitToByte(MesOut,MesBit,);
}

C语言实现DES算法的更多相关文章

  1. DES算法与四种加密模式的代码实现(C++语言)

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/Love_Irelia97/article/ ...

  2. C语言单片和C#语言服务器端DES及3DES加密的实现

    原文:C语言单片和C#语言服务器端DES及3DES加密的实现 公司最近在做单片机和C#语言的通信.用的是Socket通信.传输的数据是明文,后来 在会上讨论准备用DES加密(对称加密)来做. 双方约定 ...

  3. MFC 简单实现 DES 算法

    前言 徐旭东老师说过学者就应该对知识抱有敬畏之心,所以我的博客的标题总喜欢加上"简单"二字,就是为了提醒自己,自己所学知识只是皮毛,离真理还远矣. DES 算法 DES算法是密码体 ...

  4. C#与Java同步加密解密DES算法

    在实际项目中,往往前端和后端使用不同的语言.比如使用C#开发客户端,使用Java开发服务器端.有时出于安全性考虑需要将字符加密传输后,由服务器解密获取.本文介绍一种采用DES算法的C#与Java同步加 ...

  5. iOS -- DES算法

    算法步骤: DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位(实际用到了56位,第8.16.24.32.40.48.56.64位是校验位, 使得每个密钥都有奇数个1),其 ...

  6. IDAPython实战项目——DES算法识别

    在CTF的逆向中我们需要的是找到加密的主函数,结合了yara的识别原理,通过对常量数组的引用的查找,一步步递归构建调用树.调用树根部就是可能的密码算法主函数. 由于这种办法需要常量分布于算法的各个步骤 ...

  7. 10个经典的C语言面试基础算法及代码

    10个经典的C语言面试基础算法及代码作者:码农网 – 小峰 原文地址:http://www.codeceo.com/article/10-c-interview-algorithm.html 算法是一 ...

  8. DES算法详解

    本文主要介绍了DES算法的步骤,包括IP置换.密钥置换.E扩展置换.S盒代替.P盒置换和末置换. 1.DES算法简介 DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准. DES是一个分组 ...

  9. 基于DES算法加密的防撞库密码系统项目总结

    项目内容:基于DES算法加密的防撞库密码系统 小组名:zqhzkzkj 目标:1.对用户输入的8位字符进行DES加密,要求用户输入8位密钥 2.对于不同的网站,不同的用户名生成不同的密码 小组成员:周 ...

随机推荐

  1. Java第十二次作业:继承与抽象类解决工人与学生的问题,抽象类实例。抽象类作用——为多态创造了可能。抽象类的作用总结

    继承与抽象类解决工人与学生的问题 抽象类实例 package com.swift; public abstract class Person { private String name; privat ...

  2. 协议(Protocol)与委托代理(Delegate)

    协议(Protocol)的作用: 1. 规范接口,用来定义一套公用的接口: 2. 约束或筛选对象. 代理(Delegate): 它本身是一种设计模式,委托一个对象<遵守协议>去做某件事情, ...

  3. html5新结构标签

    html5新结构标签 <header>  定义 section 或 page 的页眉,也就是定义头部的标签. <footer> 定义 section 或 page 的页脚. & ...

  4. PHP使用FTP上传文件到服务器(实战篇)

    我们在做开发的过程中,上传文件肯定是避免不了的,平常我们的程序和上传的文件都在一个服务器上,我们也可以使用第三方sdk上传文件,但是文件在第三方服务器上.现在我们使用PHP的ftp功能把文件上传到我们 ...

  5. 通过代码链接ftp上传下载删除文件

    因为我的项目是Maven项目,首先要导入一个Maven库里的包:pom.xml <dependency>            <groupId>com.jcraft</ ...

  6. 中国电信物联网平台入门学习笔记7:NB-IOT信号如何检测

    NB-IOT设备会因为信号的原因,数据发不出.但数据发不出的原因有很多,这么排除是NB-IOT信号的问题呢?那就需要NB-IOT信号检测装置. 网上的信号检测设备 作为一个常年蜗居在实验室的穷屌丝而言 ...

  7. STM32F407VET6之IAR之ewarm7.80.4工程建立(基于官方固件库1.6版本)

    今天把stm32F407的工程之IAR建立完成了,特此记录下. 下载官方固件库,STM32F4xx_DSP_StdPeriph_Lib_V1.6.1,V1.8.0版本的同理.新建以下几个文件 src放 ...

  8. JavaSE——final修饰符

    一.final 修饰变量,被final修饰的变量在被赋初始值之后,不能对它重新赋值 修饰实例变量,必须显示指定初始值,可以在三个位置指定初始值:         1.定义final实例变量时指定初始值 ...

  9. 打造一款属于自己的web服务器——从简单开始

    距离开篇已经过了很久,期间完善了一下之前的版本,目前已经能够完好运行,基本上该有的功能都有了,此外将原来的测试程序改为示例项目,新项目只需按照示例项目结构实现controller和view即可,详情见 ...

  10. 光学字符识别OCR-7语言模型

    由于图像质量等原因,性能再好的识别模型,都会有识别错误的可能性,为了减少识别错误率,可以将识别问题跟统计语言模型结合起来,通过动态规划的方法给出最优的识别结果.这是改进OCR识别效果的重要方法之一. ...