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

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

1、VC6 Win32 Console Application

  1. /*-------------------------------------------------------
  2. Data Encryption Standard 56位密钥加密64位数据
  3. 2011.10
  4. --------------------------------------------------------*/
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include "bool.h" // 位处理
  8. #include "tables.h"
  9.  
  10. void BitsCopy(bool *DatOut,bool *DatIn,int Len); // 数组复制
  11.  
  12. void ByteToBit(bool *DatOut,char *DatIn,int Num); // 字节到位
  13. void BitToByte(char *DatOut,bool *DatIn,int Num); // 位到字节
  14.  
  15. void BitToHex(char *DatOut,bool *DatIn,int Num); // 二进制到十六进制 64位 to 4*16字符
  16. void HexToBit(bool *DatOut,char *DatIn,int Num); // 十六进制到二进制
  17.  
  18. void TablePermute(bool *DatOut,bool *DatIn,const char *Table,int Num); // 位表置换函数
  19. void LoopMove(bool *DatIn,int Len,int Num); // 循环左移 Len长度 Num移动位数
  20. void Xor(bool *DatA,bool *DatB,int Num); // 异或函数
  21.  
  22. void S_Change(bool DatOut[],bool DatIn[]); // S盒变换
  23. void F_Change(bool DatIn[],bool DatKi[]); // F函数
  24.  
  25. void SetKey(char KeyIn[]); // 设置密钥
  26. void PlayDes(char MesOut[],char MesIn[]); // 执行DES加密
  27. void KickDes(char MesOut[],char MesIn[]); // 执行DES解密
  28.  
  29. int main()
  30. {
  31. int i=;
  32. char MesHex[]={}; // 16个字符数组用于存放 64位16进制的密文
  33. char MyKey[]={}; // 初始密钥 8字节*8
  34. char YourKey[]={}; // 输入的解密密钥 8字节*8
  35. char MyMessage[]={}; // 初始明文
  36.  
  37. /*-----------------------------------------------*/
  38.  
  39. printf("Welcome! Please input your Message(64 bit):\n");
  40. gets(MyMessage); // 明文
  41. printf("Please input your Secret Key:\n");
  42. gets(MyKey); // 密钥
  43.  
  44. while(MyKey[i]!='\0') // 计算密钥长度
  45. {
  46. i++;
  47. }
  48.  
  49. while(i!=) // 不是8 提示错误
  50. {
  51. printf("Please input a correct Secret Key!\n");
  52. gets(MyKey);
  53. i=;
  54. while(MyKey[i]!='\0') // 再次检测
  55. {
  56. i++;
  57. }
  58. }
  59.  
  60. SetKey(MyKey); // 设置密钥 得到子密钥Ki
  61.  
  62. PlayDes(MesHex,MyMessage); // 执行DES加密
  63.  
  64. printf("Your Message is Encrypted!:\n"); // 信息已加密
  65. for(i=;i<;i++)
  66. {
  67. printf("%c ",MesHex[i]);
  68. }
  69. printf("\n");
  70. printf("\n");
  71.  
  72. printf("Please input your Secret Key to Deciphering:\n"); // 请输入密钥以解密
  73. gets(YourKey); // 得到密钥
  74. SetKey(YourKey); // 设置密钥
  75.  
  76. KickDes(MyMessage,MesHex); // 解密输出到MyMessage
  77.  
  78. printf("Deciphering Over !!:\n"); // 解密结束
  79. for(i=;i<;i++)
  80. {
  81. printf("%c ",MyMessage[i]);
  82. }
  83. printf("\n");
  84. system("pause");
  85.  
  86. /*------------------------------------------------*/
  87. }
  88.  
  89. /*-------------------------------
  90. 把DatIn开始的长度位Len位的二进制
  91. 复制到DatOut后
  92. --------------------------------*/
  93. void BitsCopy(bool *DatOut,bool *DatIn,int Len) // 数组复制 OK
  94. {
  95. int i=;
  96. for(i=;i<Len;i++)
  97. {
  98. DatOut[i]=DatIn[i];
  99. }
  100. }
  101.  
  102. /*-------------------------------
  103. 字节转换成位函数
  104. 每8次换一个字节 每次向右移一位
  105. 和1与取最后一位 共64位
  106. --------------------------------*/
  107. void ByteToBit(bool *DatOut,char *DatIn,int Num) // OK
  108. {
  109. int i=;
  110. for(i=;i<Num;i++)
  111. {
  112. DatOut[i]=(DatIn[i/]>>(i%))&0x01;
  113. }
  114. }
  115.  
  116. /*-------------------------------
  117. 位转换成字节函数
  118. 字节数组每8次移一位
  119. 位每次向左移 与上一次或
  120. ---------------------------------*/
  121. void BitToByte(char *DatOut,bool *DatIn,int Num) // OK
  122. {
  123. int i=;
  124. for(i=;i<(Num/);i++)
  125. {
  126. DatOut[i]=;
  127. }
  128. for(i=;i<Num;i++)
  129. {
  130. DatOut[i/]|=DatIn[i]<<(i%);
  131. }
  132. }
  133.  
  134. /*----------------------------------
  135. 二进制密文转换为十六进制
  136. 需要16个字符表示
  137. -----------------------------------*/
  138. void BitToHex(char *DatOut,bool *DatIn,int Num)
  139. {
  140. int i=;
  141. for(i=;i<Num/;i++)
  142. {
  143. DatOut[i]=;
  144. }
  145. for(i=;i<Num/;i++)
  146. {
  147. DatOut[i] = DatIn[i*]+(DatIn[i*+]<<)
  148. +(DatIn[i*+]<<)+(DatIn[i*+]<<);
  149. if((DatOut[i]%)>)
  150. {
  151. DatOut[i]=DatOut[i]%+''; // 余数大于9时处理 10-15 to A-F
  152. } // 输出字符
  153. else
  154. {
  155. DatOut[i]=DatOut[i]%+''; // 输出字符
  156. }
  157. }
  158.  
  159. }
  160.  
  161. /*---------------------------------------------
  162. 十六进制字符转二进制
  163. ----------------------------------------------*/
  164. void HexToBit(bool *DatOut,char *DatIn,int Num)
  165. {
  166. int i=; // 字符型输入
  167. for(i=;i<Num;i++)
  168. {
  169. if((DatIn[i/])>'') // 大于9
  170. {
  171. DatOut[i]=((DatIn[i/]-'')>>(i%))&0x01;
  172. }
  173. else
  174. {
  175. DatOut[i]=((DatIn[i/]-'')>>(i%))&0x01;
  176. }
  177. }
  178. }
  179.  
  180. // 表置换函数 OK
  181. void TablePermute(bool *DatOut,bool *DatIn,const char *Table,int Num)
  182. {
  183. int i=;
  184. static bool Temp[]={};
  185. for(i=;i<Num;i++) // Num为置换的长度
  186. {
  187. Temp[i]=DatIn[Table[i]-]; // 原来的数据按对应的表上的位置排列
  188. }
  189. BitsCopy(DatOut,Temp,Num); // 把缓存Temp的值输出
  190. }
  191.  
  192. // 子密钥的移位
  193. void LoopMove(bool *DatIn,int Len,int Num) // 循环左移 Len数据长度 Num移动位数
  194. {
  195. static bool Temp[]={}; // 缓存 OK
  196. BitsCopy(Temp,DatIn,Num); // 将数据最左边的Num位(被移出去的)存入Temp
  197. BitsCopy(DatIn,DatIn+Num,Len-Num); // 将数据左边开始的第Num移入原来的空间
  198. BitsCopy(DatIn+Len-Num,Temp,Num); // 将缓存中移出去的数据加到最右边
  199. }
  200.  
  201. // 按位异或
  202. void Xor(bool *DatA,bool *DatB,int Num) // 异或函数
  203. {
  204. int i=;
  205. for(i=;i<Num;i++)
  206. {
  207. DatA[i]=DatA[i]^DatB[i]; // 异或
  208. }
  209. }
  210.  
  211. // 输入48位 输出32位 与Ri异或
  212. void S_Change(bool DatOut[],bool DatIn[]) // S盒变换
  213. {
  214. int i,X,Y; // i为8个S盒
  215. for(i=,Y=,X=;i<;i++,DatIn+=,DatOut+=) // 每执行一次,输入数据偏移6位
  216. { // 每执行一次,输出数据偏移4位
  217. Y=(DatIn[]<<)+DatIn[]; // af代表第几行
  218. X=(DatIn[]<<)+(DatIn[]<<)+(DatIn[]<<)+DatIn[]; // bcde代表第几列
  219. ByteToBit(DatOut,&S_Box[i][Y][X],); // 把找到的点数据换为二进制
  220. }
  221. }
  222.  
  223. // F函数
  224. void F_Change(bool DatIn[],bool DatKi[]) // F函数
  225. {
  226. static bool MiR[]={}; // 输入32位通过E选位变为48位
  227. TablePermute(MiR,DatIn,E_Table,);
  228. Xor(MiR,DatKi,); // 和子密钥异或
  229. S_Change(DatIn,MiR); // S盒变换
  230. TablePermute(DatIn,DatIn,P_Table,); // P置换后输出
  231. }
  232.  
  233. void SetKey(char KeyIn[]) // 设置密钥 获取子密钥Ki
  234. {
  235. int i=;
  236. static bool KeyBit[]={}; // 密钥二进制存储空间
  237. static bool *KiL=&KeyBit[],*KiR=&KeyBit[]; // 前28,后28共56
  238. ByteToBit(KeyBit,KeyIn,); // 把密钥转为二进制存入KeyBit
  239. TablePermute(KeyBit,KeyBit,PC1_Table,); // PC1表置换 56次
  240. for(i=;i<;i++)
  241. {
  242. LoopMove(KiL,,Move_Table[i]); // 前28位左移
  243. LoopMove(KiR,,Move_Table[i]); // 后28位左移
  244. TablePermute(SubKey[i],KeyBit,PC2_Table,);
  245. // 二维数组 SubKey[i]为每一行起始地址
  246. // 每移一次位进行PC2置换得 Ki 48位
  247. }
  248. }
  249.  
  250. void PlayDes(char MesOut[],char MesIn[]) // 执行DES加密
  251. { // 字节输入 Bin运算 Hex输出
  252. int i=;
  253. static bool MesBit[]={}; // 明文二进制存储空间 64位
  254. static bool Temp[]={};
  255. static bool *MiL=&MesBit[],*MiR=&MesBit[]; // 前32位 后32位
  256. ByteToBit(MesBit,MesIn,); // 把明文换成二进制存入MesBit
  257. TablePermute(MesBit,MesBit,IP_Table,); // IP置换
  258. for(i=;i<;i++) // 迭代16次
  259. {
  260. BitsCopy(Temp,MiR,); // 临时存储
  261. F_Change(MiR,SubKey[i]); // F函数变换
  262. Xor(MiR,MiL,); // 得到Ri
  263. BitsCopy(MiL,Temp,); // 得到Li
  264. }
  265. TablePermute(MesBit,MesBit,IPR_Table,);
  266. BitToHex(MesOut,MesBit,);
  267. }
  268.  
  269. void KickDes(char MesOut[],char MesIn[]) // 执行DES解密
  270. { // Hex输入 Bin运算 字节输出
  271. int i=;
  272. static bool MesBit[]={}; // 密文二进制存储空间 64位
  273. static bool Temp[]={};
  274. static bool *MiL=&MesBit[],*MiR=&MesBit[]; // 前32位 后32位
  275. HexToBit(MesBit,MesIn,); // 把密文换成二进制存入MesBit
  276. TablePermute(MesBit,MesBit,IP_Table,); // IP置换
  277. for(i=;i>=;i--)
  278. {
  279. BitsCopy(Temp,MiL,);
  280. F_Change(MiL,SubKey[i]);
  281. Xor(MiL,MiR,);
  282. BitsCopy(MiR,Temp,);
  283. }
  284. TablePermute(MesBit,MesBit,IPR_Table,);
  285. BitToByte(MesOut,MesBit,);
  286. }

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. 01_9_ServletContext

    01_9_ServletContext 1. 例子 public void doGet(HttpServletRequest request, HttpServletResponse response ...

  2. 空类生成对象输出的结果是什么? toString()输出 覆写Object toString()方法输出的结果是什么

    空类生成对象输出的结果是什么? 输出的是对象在内存空间地址的哈希值 com.swift.P@1db9742 空类生成对象toString()输出的结果是什么? 输出的是对象在内存空间地址的哈希值的字符 ...

  3. on() 和 click() 的区别

    on() 和 click() 的区别: 二者在绑定静态控件时没有区别,但是如果面对动态产生的控件,只有 on() 能成功的绑定到动态控件中. 以下实例中原先的 HTML 元素点击其身后的 Delete ...

  4. 35. Search Insert Position@python

    Given a sorted array and a target value, return the index if the target is found. If not, return the ...

  5. 第6章 AOP与全局异常处理6.5-6.11 慕课网微信小程序开发学习笔记

    https://coding.imooc.com/learn/list/97.html 目录: 第6章 AOP与全局异常处理6-1 正确理解异常处理流程 13:236-2 固有的处理异常的思维模式与流 ...

  6. LeetCode(258) Add Digits

    题目 Given a non-negative integer num, repeatedly add all its digits until the result has only one dig ...

  7. PAT Basic 1076

    1076 Wifi密码 下面是微博上流传的一张照片:“各位亲爱的同学们,鉴于大家有时需要使用 wifi,又怕耽误亲们的学习,现将 wifi 密码设置为下列数学题答案:A-1:B-2:C-3:D-4:请 ...

  8. 启动Chrome浏览器弹出“You are using an unsupported command-line flag –ignore-certificate-errors. Stability and security will suffer”

    采用如下代码: public static void launchChrome() { System.setProperty("webdriver.chrome.driver", ...

  9. Pycharm Django开发(一)设置开发环境

    一 由于我是一个对开发环境有强迫症的人,在装完PYTHON 2.6 3.3  3.4中,在创建Django工程的时候,会出现N个版本的python,那么在这里可以设置你喜欢和要使用的版本.

  10. 【NOIP2017】 列队

    线段树博客先开个点随笔.... 这意味着啥呢? 今天绝对要把这道题写出来并且更掉这篇blog!!!! ~ upd:懂了哈哈哈哈哈哈哈 先贴代码 回家+讲解 ---------------------- ...