DES密码算法

代码放这留备份。

#include<iostream>
#include<cstring>
using namespace std;

const static char S_Box[8][4][16] = {       //S盒置换
	// S1
	14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
	0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
	4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
	15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
	// S2
	15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
	3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
	0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
	13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
	// S3
	10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
	13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
	13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
	1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
	// S4
	7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
	13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
	10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
	3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
	// S5
	2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
	14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
	4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
	11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
	// S6
	12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
	10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
	9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
	4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
	// S7
	4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
	13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
	1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
	6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
	// S8
	13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
	1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
	7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
	2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
};
const static char IP[64] = {          //P置换
	58, 50, 42, 34, 26, 18, 10, 2,
    60, 52, 44, 36, 28, 20, 12, 4,
    62, 54, 46, 38, 30, 22, 14, 6,
    64, 56, 48, 40, 32, 24, 16, 8,
    57, 49, 41, 33, 25, 17,  9, 1,
    59, 51, 43, 35, 27, 19, 11, 3,
    61, 53, 45, 37, 29, 21, 13, 5,
    63, 55, 47, 39, 31, 23, 15, 7
};
const static char FP[64] = {          //P逆置换
	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
};
const static char EP[48] = {         //拓展置换
	32,  1,  2,  3,  4,  5,  4,  5,
     6,  7,  8,  9,  8,  9, 10, 11,
    12, 13, 12, 13, 14, 15, 16, 17,
    16, 17, 18, 19, 20, 21, 20, 21,
    22, 23, 24, 25, 24, 25, 26, 27,
    28, 29, 28, 29, 30, 31, 32,  1
};
const static char SP[32] = {     //P置换
    16,  7, 20, 21,
	29, 12, 28, 17,
     1, 15, 23, 26,
	 5, 18, 31, 10,
     2,  8, 24, 14,
	32, 27,  3,  9,
    19, 13, 30,  6,
	22, 11,  4, 25
};
const static char PC1[56] = {                    //置换选择1
    57, 49, 41, 33, 25, 17,  9,  1,
    58, 50, 42, 34, 26, 18, 10,  2,
    59, 51, 43, 35, 27, 19, 11,  3,
    60, 52, 44, 36, 63, 55, 47, 39,
    31, 23, 15,  7, 62, 54, 46, 38,
    30, 22, 14,  6, 61, 53, 45, 37,
    29, 21, 13,  5, 28, 20, 12,  4
};
const static char PC2[48] = {               //置换选择2
    14, 17, 11, 24,  1,  5,  3, 28,
    15,  6, 21, 10, 23, 19, 12,  4,
    26,  8, 16,  7, 27, 20, 13,  2,
    41, 52, 31, 37, 47, 55, 30, 40,
    51, 45, 33, 48, 44, 49, 39, 56,
    34, 53, 46, 42, 50, 36, 29, 32
};
const static char LOOP[16]={
	1, 1, 2, 2, 2, 2, 2, 2,
	1, 2, 2, 2, 2, 2, 2, 1
};

bool key[16][48];

void ByteToBit(char *In, bool *Out, int bits)    //字节到位
{
	for(int i=0;i<bits;++i)
		Out[i] = (In[i/8]>>(i%8))&1;
}
void BitToByte(bool *In, char *Out, int bits)   //位到字节
{
	memset(Out,0,bits/8);
	for(int i=0;i<bits;++i)
		Out[i/8] |= In[i]<<(i%8);
}
void Transform(bool *In, bool *Out, const char *Table, int len)  //置换函数
{
	static bool temp[128];
	for(int i=0; i<len; ++i)
		temp[i] = In[Table[i] - 1];
	memcpy(Out,temp,len);
}
void CirculateMove(bool *In, int len,const char s)   //循环左移
{
	static bool temp[128];
	memcpy(temp, In, len);
	for(int i=0; i<len; ++i)
		In[i]=temp[(i+s)%len];
}
void RoundKey(char initKey[8])     //计算轮密钥
{
	static bool keyBits[64], crypKeyBits[56];
	ByteToBit(initKey, keyBits, 64);
	Transform(keyBits, crypKeyBits,  PC1, 56);
	for(int i=0; i<16; ++i)
	{
		CirculateMove(crypKeyBits, 28, LOOP[i]);
		CirculateMove(&crypKeyBits[28], 28, LOOP[i]);
		Transform(crypKeyBits, key[i], PC2, 48);
	}
}
void Xor(bool *Out, bool *In, int len)    ///异或运算
{
	for(int i=0; i<len; ++i)
		Out[i] ^= In[i];
}
void S(bool In[48], bool Out[32])         //S盒替换
{
	int x, y;
	char c;
	for(int i=0; i<8; i++, In+=6)
	{
		x = In[0] * 2 + In[5];
		y = In[1] * 8 + In[2] * 4 + In[3] * 2 + In[4];
		c = S_Box[i][x][y];
		Out[4*i] = (c%2)&1;
		Out[4*i+1] = ((c/2)%2)&1;
		Out[4*i+2] = ((c/4)%2)&1;
		Out[4*i+3] = ((c/8)%2)&1;
	}
}
void FE(bool In[64], bool thisKey[48])    //轮函数
{
	static bool temp[128],afterEP[48];
	memcpy(temp,&In[32],32);
	Transform(&In[32], afterEP, EP, 48);

	Xor(afterEP,thisKey,48);
	S(afterEP,&In[32]);
	Transform(&In[32], &In[32], SP, 32);
	Xor(&In[32], In, 32);
	memcpy(In, temp, 32);

}

void FD(bool In[64], bool thisKey[48])    //轮函数
{
	static bool temp[128],afterEP[48];
	memcpy(temp,In,32);
	Transform(In, afterEP, EP, 48);
	Xor(afterEP,thisKey,48);
	S(afterEP,In);
	Transform(In, In, SP, 32);
	Xor(In, &In[32], 32);
	memcpy(&In[32], temp, 32);

}
void Encrypt(char In[8], char Out[8])   //加密
{
	static bool bits[64];
	ByteToBit(In,bits,64);
	Transform(bits,bits,IP,64);
	for(int i=0; i<16; ++i)
		FE(bits,key[i]);
	Transform(bits, bits, FP, 64);
	BitToByte(bits, Out, 64);
}
void Decrypt(char In[8], char Out[8])   //加密
{
	static bool bits[64];
	ByteToBit(In,bits,64);
	Transform(bits,bits,IP,64);
	for(int i=15; i>=0; i--)
		FD(bits,key[i]);
	Transform(bits, bits, FP, 64);
	BitToByte(bits, Out, 64);
}
int main()
{
	char c;
	char initKey[9];
	cout<<"============= DES密码算法 =============="<<endl<<endl;
	cout<<"请设定8位字符的密钥:"<<endl;
	cin>>initKey;
	RoundKey(initKey);
	cin.get(c);
	char plainText[256],crypText[256],newPlainText[256];
	cout<<endl<<"请输入要加密的明文(支持空格和中文):"<<endl;
	cin.getline(plainText,256);
	int l=strlen(plainText);
	if(l%8!=0)          //如果长度不是8的倍数,以空格填充
	{
		int newL = 8*(l/8+1);
		for(int i=l;i < newL;i++)
			plainText[i]=' ';
	}
	for(int i=0;i<l;i+=8)
		Encrypt(plainText+i,crypText+i);
	cout<<endl<<"您的明文加密后结果如下:"<<endl;
	for(int i=0;i<l;i++)
		cout<<crypText[i];
	cout<<endl<<"-------------------------------------"<<endl;
	cout<<"请输入您之前设定的8位密钥来进行解密:"<<endl;
	cin>>initKey;
	RoundKey(initKey);
	for(int i=0;i<l;i+=8)
		Decrypt(crypText+i,newPlainText+i);
	cout<<endl<<"您的密文解密后结果如下:"<<endl;
	for(int i=0;i<l;i++)
		cout<<newPlainText[i];
	cout<<endl<<endl<<"DES密码算法完成!"<<endl;
	system("pause");
	return 0;
}
时间: 2024-10-12 18:43:07

DES密码算法的相关文章

密码算法详解——DES

0 DES简介 在20世纪60年代后期,IBM公司成立了一个由Horst Feistel负责的计算机密码学研究项目.1971年设计出算法LUCIFER后,该项目宣告结束.LUCIFER被卖给了伦敦的Lloyd公司,用在同样由IBM公司开发的现金发放系统上.LUCIFER是分组长度为64位.密钥长度为128位.具有Feistel结构的分组密码.因为LUCIFER非常成功,IBM决定开发一个适合于芯片实现的商业密码产品.这一次由Walter Tuchman和Carl Meyer牵头,参与者不仅有IB

弱密码算法简单汇总

整理一下非安全的弱密码算法,在使用时要注意. 一.加解密算法(cipher) 3des_cbc 3DES algorithm des_cbc DES algorithm aes128_cbc AES128 algorithm aes128_ctr AES128_CTR algorithm aes192_cbc  AES192 algorithm aes192_ctr AES192_CTR algorithm aes256_cbc AES256 algorithm aes256_ctr AES25

Android中锁屏密码算法解析以及破解方案

一.前言 最近玩王者荣耀,下载了一个辅助样本,结果被锁机了,当然破解它很简单,这个后面会详细分析这个样本,但是因为这个样本引发出的欲望就是解析Android中锁屏密码算法,然后用一种高效的方式制作锁机恶意样本.现在的锁机样本原理强制性太过于复杂,没意义.所以本文就先来介绍一下android中的锁屏密码算法原理. 二.锁屏密码方式 我们知道Android中现结单支持的锁屏密码主要有两种: 一种是手势密码,也就是我们常见的九宫格密码图 一种是输入密码,这个也分为PIN密码和复杂字符密码,而PIN密码

信息安全-2:python之hill密码算法[原创]

转发注明出处:http://www.cnblogs.com/0zcl/p/6106513.html 前言: hill密码算法我打算简要介绍就好,加密矩阵我用教材上的3*3矩阵,只做了加密,解密没有做,不过我觉得会加密就会解密的~~       一.hill算法原理 hill密码是一种多字母替代密码,由数学学Leste Hill于1929年研制成功.该密码算法取m个连续的明文字母,并用m个密文字母代替,用向量或矩阵表示为(这里取m=3,C和P是长度为3的列向量,K是3*3矩阵): 即:C=KP  

国家商业密码算法开放动态库及演示程序

 开放动态库支持如下国家商业密码算法:SM2.SM3.SM4,同时也支持AES对称加密算法. 下载地址: 国家商业密码算法开放动态库及演示程序C#语言版 国家商业密码算法开放动态库及演示程序Java语言版 当前提供的语言版本: C#语言版本,其开发环境为:Visual Studio V2013..NET Framework 4.5 Java语言版本,其开发环境为:NetBeans 8.0.2.JDK 8u45 C/C++语言版本:暂不开放 Qt版本:暂不开放 算法说明 SM2: 支持P-25

使用CPA4破解经典密码算法

下面是一段经过经典密码算法加密的密文(加密算法未知): yvvnerujjvnywhbdvkpchfgvjtzwqsuporqfzpoekkjgziicdwwkeejdsruef   whwseyejejhnaeepjbjwnuztavjswrthswlcdxqrnoclsodkrrfjtfhlfznbx   wyvdwdcwyzqlqrnevuiiienxzmwtdsyhgstwmvznrvhyihhcxjijhiojphvjw   srpejwnhrhirqbcdwnzqmwjpoibnbj

Python 生成账号密码算法

有个需求,需要伪造跟用户行为非常类似的账号密码,而且需要一个阀值控制伪造的数量. 在这需求上,还有一个就是需要控制生成的比率.跳出率不能过高或者太低. 对此就随手用python写了一个,bug不知道有木有,没有测,具体有兴趣可以去改改. #coding:utf-8 import random class create_data: global zimu_xx,zimu_dx,number,teshu # 生成26个英文字母,大小写 zimu_xx=[chr(i) for i in range(9

UCenter密码算法规则和生成方法

如果想平滑的使用UCenter,那么这篇文章务必 康盛的系列产品,包括Discuz.UCHome.Supesite都集成了同一个用户系统--UCenter,用户登录的密码也保存在 UCenter中,对于其他系统集成或导出数据到UCenter系统,通常会遇到密码生成的问题,这里就讨论一下UCenter的用户密码算法规则和生成 方法. 密码通常使用MD5对用户密码HASH 后保存在数据库中的方法,如果黑客拿到了这个HASH数值,那么可以采用字典的方式暴力破解,如果这个字典数据库足够大,并且字典比较符

1.3.2 区块链中的密码学——椭圆曲线密码算法(ECC)

今天在学椭圆曲线密码(Elliptic Curve Cryptography,ECC)算法,自己手里缺少介绍该算法的专业书籍,故在网上查了很多博文与书籍,但是大多数博客写的真的是...你懂的...真不愧是 '天下文章一大抄' 啊! 雷同不说,关键是介绍的都不是很清楚,是我在阅读过程中.产生的很多疑问无法解决!例如:只来句'P+Q=R',但是为什么等于呢?是根据什么计算出来的呢? 后来查了好久,才发现:这是规定的.是定义!瞬间很是无语! 好了,不吐槽了,为了方便大家对椭圆曲线密码算法有系统的了解,