DES加解密算法是一个挺老的算法了,现在给出它的C语言版。

des.h

 #ifdef  __cplusplus
extern "C" {
#endif void setKey(const char key[]);
char* des(const char datas[]);
char * dedes(const char datas[]); #ifdef __cplusplus
}
#endif

des_tables.h

 char table_IP[]                /* 初始置换表 IP    */
= {
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , ,
}; const static char table_FP[] /* 末置换表 */
= {
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , ,
}; //= {
// 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
// 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
// 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
// 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25
//}; char table_PC_1[] /* 密钥置换表PC_1 */
= {
, , , , , , , , , , , , , ,
, , , , , , , , , , , , , ,
, , , , , , , , , , , , , ,
, , , , , , , , , , , , ,
}; char table_PC_2[] /* 压缩置换表 PC_2 */
= {
, , , , , , , , , , , ,
, , , , , , , , , , , ,
, , , , , , , , , , , ,
, , , , , , , , , , ,
}; char table_S[][] /* 48->32 bit compression tables*/
= { /* S[1] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
/* S[2] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
/* S[3] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
/* S[4] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
/* S[5] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
/* S[6] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
/* S[7] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
/* S[8] */
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , ,
}; char table_P[] /* P 盒置换 */
= { , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , ,
}; char table_E[]
= {
, , , , , , , , , , , ,
, , , , , , , , , , , ,
, , , , , , , , , , , ,
, , , , , , , , , , ,
}; char table_move[]
={
,,,,
,,,,
,,,,
,,,
};

des.c

 #include<stdio.h>
#include<string.h>
#include"des_tables.h"
#include"des.h" //保存这16轮的加密密钥<64位>
char keys[][];
//存着经过压缩置换后的 key
char key_48[][]; char data[];
//s盒置换结果缓冲区
char data_32[];
char *data_left;
char *data_right; //密钥置换
void fun_InitReplacementKey(){
register int i,j,l=;
register unsigned int k;
register char *to_pos = keys[];
memset(to_pos,,);
for(i=,l=;i<;i++){
for(j=;j>;j--){
k = table_PC_1[l++]-;
*to_pos = (*to_pos)| (( (*(keys[]+(k>>)) >>( - (k&0x07) ))&0x01 )<<j);
} to_pos++;
}
} //对密钥进行移位,并存在接下来下面的字节中
void fun_MoveKey(int len , char*offset, char *dist){
/////////////////////////
///错误了!!!! 是分两块进行循环移位 !!!!!!!
///< 已修改 ! 需要分左右部分 > register int i = len;
unsigned char firstBit;
static unsigned char *tmp;
tmp =(unsigned char*)dist;
memcpy(tmp,offset,);
firstBit =(unsigned char)tmp[];
firstBit = firstBit>>(-len); //左边部分循环左移
for(i=;i< ;i++){
tmp[i] = (tmp[i]&0xfe) <<len ;
tmp[i] = tmp[i]|((tmp[i+]>>(-len))&0xff);
tmp[i] = tmp[i]&0xfe;
} tmp[i] = (tmp[i] &0xfe)<<len;
tmp[i] = tmp[i]|(firstBit<<);
tmp[i] = tmp[i]&0xfe; firstBit =(unsigned char)tmp[++i];
firstBit = firstBit>>(-len); //右边部分循环左移
for(i;i<;i++){
tmp[i] = (tmp[i]&0xfe) <<len ;
tmp[i] = tmp[i]|((tmp[i+]>>(-len))&0xff);
tmp[i] = tmp[i]&0xfe;
}
tmp[i] = (tmp[i] &0xfe)<<len;
tmp[i] = tmp[i]|(firstBit<<);
tmp[i] = tmp[i]&0xfe; } //对密钥进行压缩置换并保存到指定位置
void fun_ReplacementCompressKey(char* offset,char *dist){
//压缩置换是在 0-56位进行.需要先对64位密钥进行压缩为56位在进行48位选择
register int i,j,k,l;
register char dt;
register unsigned char* tmp = (unsigned char*)offset;
char mid_tmp[]; for(i=;i<;i++){
mid_tmp[i] = (tmp[i]<<(i)) | ((tmp[i+])>>(-i));
} memset(dist,,);
//进行置换
for(i=,l=;i<;i++){
for(dt =,j=;j>=;j--){
k = table_PC_2[l++]-;
dt = dt|(( (*(mid_tmp+(k>>)) >>( - k&0x07 ))&0x01 )<<j);
if(j==)
break;
}
dist[i] = dt;
}
} /**********************************************/ /**********************************************/
//加密过程 //初始置换 ip
//从offset位置开始将数据置换到 data[8-15]字节 ,然后重新复制到data[0-7]中
void fun_initReplacement(const char *offset){
register int i,j,l;
register unsigned char k,*tmp,*to;
//将数据块区域重置为 0
tmp = (unsigned char*)offset;
to = (unsigned char* )(data+);
memset(to,,);
for(i=,l=;i<;i++){
for(j=;j>=;j--){
k = table_IP[l++]-;
to[i] = to[i] | ((( *(tmp+(k>>))>>(- (k &0x07)))&0x01)<<j);
if(j==)
break;
}
}
memcpy(data,data+,);
//初始化指针
data_left = data;
data_right = data+;
} //末置换 fp
void fun_finalReplacement(){
//数据块存在 data[0]-data[7]中 !
//置换临时空间 data[8]-data[15]
register int i,j,l;
register unsigned char k,*tmp,*to;
//将数据块区域重置为 0
tmp = (unsigned char*)data;
to = (unsigned char*)(data+);
for(i=,l=;i<;i++){
for(j=;j>=;j--){
k = table_FP[l++]-;
to[i] = to[i] | ((( *(tmp+(k>>))>>(- (k &0x07)))&0x01)<<j);
if(j==)
break;
}
}
memcpy(data,to,); } //扩展置换
void fun_expandReplacement_32To48(){
//////////将右边的数据扩展至 48 位 !
register int i,j;
register unsigned char k,l,*tmp,*to_pos;
tmp = (unsigned char *)data_right;
to_pos = (unsigned char*)(data+);
memset(to_pos,,);
//printf("\n---------- 扩展置换 ---------\n");
for(i=,l=;i<;i++){
for(j= ,k=;j>=;j--){
k = table_E[l++]-;
*to_pos = (*to_pos)| (((*(tmp+(k>>)) >>( - (k&0x07) ))&0x01)<<j);
//printf("%d %d %x \n",l,k,((*(tmp+(k>>3)) >>(7 - (k&0x07) ))&0x01));
if(j==)
break;
}
to_pos++;
}
} //加 密钥 异或
void fun_xor_48(char *ktmp){
register int i;
char *dtmp = data+;
for(i=;i<;i++){
dtmp[i] = dtmp[i]^ktmp[i]; }
} // s盒置换
void fun_S_Replacement(){
// s盒工作原理 : 48位 分成8组.每组6位 0位和5位组成行定位, 1-4位组成列定位.
// 定位出来的数据即为替换后的 4 位数据
register unsigned char row,col,ctmp,index,i;
register char *dtmp;
static char tmp[];
dtmp = data+;
memset(tmp,,);
//((*(tmp+(k>>3)) >>(7 - (k&0x07) ))&0x01)
for(index =,ctmp=,i=;i< ;i++){
// row 为:index 接下来第零位和第五位
row = (((*(dtmp+((index)>>))>>((-((index)&0x07))))&0x01)<<); //第0位
row|=(((*(dtmp+((index+)>>))>>((-((index+)&0x07))))&0x01))&0x03;//第5位 col =(((*(dtmp+((index+)>>))>>((-((index+)&0x07))))&0x01)<<); //第1位
col|= (((*(dtmp+((index+)>>))>>((-((index+)&0x07))))&0x01)<<); //第2位
col|= (((*(dtmp+((index+)>>))>>((-((index+)&0x07))))&0x01)<<); //第3位
col|= (((*(dtmp+((index+)>>))>>((-((index+)&0x07))))&0x01))&0x0f;//第4位
ctmp = table_S[i][(row<<)+col]; //写入4位
tmp[i>>] = tmp[i>>] | ((ctmp&0xf)<<(((~i)&0x01)<<));
index+=;
}
memcpy(data+,tmp,);
} //P盒置换
void fun_P_Replacement(){
register unsigned char i,k,l;
static char tmp[],j;
register char *offset =data + ;
memset(tmp,,);
for(i=,l=;i<;i++){
for(k=,j=;j>=;j--){
k = table_P[l++]-;
tmp[i] = tmp[i] |((( * (offset+(k>>)))>>( - (k&0x07))&0x01)<<j);
if(j==)
break;
}
}
memcpy(data+,tmp,);
} //左右域异或
void fun_xor_32(){
register char i;
for(i=;i<;i++){
data_left[i] = data_left[i]^data[+i];
}
} //设置 密码 <生成过程所有密码>
void setKey(const char key[]){
register int i;
register char*offset,*to,*ct;
memcpy(keys[],key,);
fun_InitReplacementKey();
offset = keys[];
to = keys[];
ct = key_48[];
//16轮迭代算出需要的 <key>
for(i=;i<;i++){
fun_MoveKey(table_move[i],offset,to);
fun_ReplacementCompressKey(to,ct);
offset = to;
ct+=;
to+=;
}
} //加密
char* des(const char datas[]){
int i=;
static char *swapeTmp;
fun_initReplacement(datas);
for(i=;i<;i++){
fun_expandReplacement_32To48();
fun_xor_48(key_48[i]);
fun_S_Replacement();
fun_P_Replacement();
fun_xor_32();
swapeTmp = data_left;
data_left =data_right;
data_right =swapeTmp;
}//经检验前 15 轮可以正确运算...
{//第16轮
fun_expandReplacement_32To48();
fun_xor_48(key_48[i]);
fun_S_Replacement();
fun_P_Replacement();
fun_xor_32();
//printf("\n---- 16 轮-----\nData: %x Left: %x Right: %x ",data,data_left,data_right);
//现在状况是 data<right,left>需要将 left 和right的数据块调换过来!!!!!!
memcpy(data+,data,);
memcpy(data,data+,);
memcpy(data+,data+,);
memset(data+,,);
}
//末置换!
fun_finalReplacement();
return data;
} //解密算法
char * dedes(const char datas[]){
int i=;
static char *swapeTmp;
fun_initReplacement(datas);
for(i=;i>;i--){
fun_expandReplacement_32To48();
fun_xor_48(key_48[i]);
fun_S_Replacement();
fun_P_Replacement();
fun_xor_32();
swapeTmp = data_left;
data_left =data_right;
data_right =swapeTmp;
}//经检验前 15 轮可以正确运算...
{//第16轮
fun_expandReplacement_32To48();
fun_xor_48(key_48[i]);
fun_S_Replacement();
fun_P_Replacement();
fun_xor_32();
//现在状况是 data<right,left>需要将 left 和right的数据块调换过来!!!!!!
memcpy(data+,data,);
memcpy(data,data+,);
memcpy(data+,data+,);
memset(data+,,);
}
//末置换!
fun_finalReplacement();
data[]='\0';
return data;
}

DES解码的更多相关文章

  1. DES加密后get获取url参数无法解密问题

    参考:http://www.cnblogs.com/lori/archive/2011/09/08/2170979.html 问题,就是URL编码问题,如果不对URL进行编码直接加码,那么在解码时,如 ...

  2. python实现软件的注册功能(机器码+注册码机制)

    http://www.cnblogs.com/cquptzzq/p/5940583.html 一.前言: 目的:完成已有python图像处理工具的注册功能 功能:用户运行程序后,通过文件自动检测认证状 ...

  3. java web实现 忘记密码(找回密码)功能及代码

    java web实现 忘记密码(找回密码)功能及代码 (一).总体思路 (二).部分截图 (三).部分代码 (一).总体思路: 1.在 找回密码页面 录入 姓名.邮箱和验证码,录入后点击[提交]按钮, ...

  4. java 加密与解密艺术

    视频来自黑马程序员公开课 对称加密之后的密文可能存在乱码,这些乱码无法识别,信息经过加密后会变成一串毫无规律的二进制串,此时再选择一种编码方式来展示,通常是 BASE64 格式的编码. 为了解决这个问 ...

  5. MD5、SHA1、DES加密和解密,Base64编码解码

    /// <summary> /// EncryptHelper 来自 www.Admin10000.com /// </summary> public class Encryp ...

  6. 3个著名加密算法(MD5、RSA、DES)的解析

    MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Security Inc发明,经MD2.MD3和MD4发展而来.    M ...

  7. DES跨(C# Android IOS)三个平台通用的加解密方法

          #region   跨平台加解密(c# 安卓 IOS)       //  public static string sKey = "12345678";       ...

  8. Java和C/C++进行DES/AES密文传输(借鉴)

    Java和C/C++进行DES/AES密文传输 声明:对于新手来说很难解决的一个问题,终于在非常煎熬之后找到这篇文章,所以借鉴过来.原文地址http://blog.sina.com.cn/s/blog ...

  9. 浅谈DES加密算法

    一.DES加密算法介绍 1.要求密钥必须是8个字节,即64bit长度 2.因为密钥是byte[8] , 代表字符串也可以是非可见的字节,可以与Base64编码算法一起使用 3.加密.解密都需要通过字节 ...

随机推荐

  1. 安装VS的过程

    软件工程学习到第三周,我们需要下载一个新的软件,用来进行软件测试.刚开始知道的时候觉得没甚么,不就是下个软件吗!有什么大不了的,分分钟搞定的事.可是想象很美好,现实很骨感.这是一个巨大的工作量呀,不仅 ...

  2. Java Web文件上传原理分析(不借助开源fileupload上传jar包)

    Java Web文件上传原理分析(不借助开源fileupload上传jar包) 博客分类: Java Web   最近在面试IBM时,面试官突然问到:如果让你自己实现一个文件上传,你的代码要如何写,不 ...

  3. Hash开散列 拉链法

    #include<iostream> #include<cstdio> using namespace std; const int maxn=1000007; struct ...

  4. oracle impdp导入时 提示“ORA-39002: 操作无效 ORA-39070: 无法打开日志文件 ”

    第一步:首先使用DBA权限的用户创建directory,我使用system ,可以在服务器本地创建,也可以远程连接sqlplus进行创建,使用的将是服务器上面的路径.要确保创建directory时,操 ...

  5. 更改HTTP头信息

    http信息分三部分 1.请求行 GET  lizi.php  HTTP/1.1 2.HTTP头信 Host: localhost Connection: keep-alive Cache-Contr ...

  6. Halcon 笔记2 Blob分析

    1. 数组操作 2. 可视化-更新窗口 (1)单步模式-总是:则可以自动显示图像: (2)单步模式-从不:需要调用显示函数才能显示图像. (3)单步模式-清空显示:将原图清除,再显示新图 3. 图像处 ...

  7. 【Python】Python的time和datetime模块

    time 常用的有time.time()和time.sleep()函数. import time print(time.time()) 1499305554.3239055 上面的浮点数称为UNIX纪 ...

  8. Android四大组件之contentProvider(续)

    1.content provider与网页有何相似之处? contentProvider使用authority 同网站的域名类似 contentProvider还可以提供类似于网站的索引方式      ...

  9. 使用Appium上传/下载文件(push文件、pull文件)

    package com.lx.class1; import java.io.File; import java.io.IOException; import java.net.URL; import ...

  10. 【刷题】BZOJ 2260 商店购物

    Description Grant是一个个体户老板,他经营的小店因为其丰富的优惠方案深受附近居民的青睐,生意红火.小店的优惠方案十分简单有趣.Grant规定:在一次消费过程中,如果您在本店购买了精制油 ...