欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

信息安全实验--DES算法

程序员文章站 2022-04-09 10:50:15
...

不喜欢这门课,感觉太蛋疼了,不爽。。

这是第一个实验的代码,还没完成就因为特殊原因终止了,只实现了加密部分,还没界面。

发上来留个纪念。信息安全实验--DES算法
            
    
    博客分类: C&C++

 

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

/*   各种表~  */
const int IP_table[8][8] = {  //初始置换IP
	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 int E_table[8][6] = {  //扩展变换E
	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 int P_table[8][4] = {  //置换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 int IPR_table[8][8] = {  //初始逆置换IP-1
	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 int S_Boxes[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 int PC1_table[7][8] = {  //PC-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 int PC2_table[6][8] = {  //PC-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 int Shift_table[16] = {  //循环左移位数
	1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};
/*     表结束     */

int e_key[16][48];


/*    函数声明    */
void stringToBinary(string s, int a[]);
string binaryToString(int b[], int length);
void table_replace(int origin[], int *p, int row_size, int line_size);
void S_box_func(int a[]);
void XOR(int a[], int b[], int size);
void rol(int a[], int *p, int num);
void cutString(int ip[], int L[], int R[], int size);
void solutionKey(string key);
string encrypt(string plain, string key, int mode, int a[]);
void printv(int a[], int size);


int main(){
	string plain, key, cipher, test;
	//char ca[16][48];
	int a[64], mode;
	//int i, j;
	while(cin>>plain>>key>>mode){
		test = encrypt(plain, key, mode, a);
		cout<<test<<endl;
		printv(a, 64);
	}

	system("pause");
	return 0;
}


/*    函数定义    */


//字符串转二进制(必须8个字符)
void stringToBinary(string s, int a[]){
	//int size = s.length();
	int i, j = 0, k, t;
	for (i = 0; s[i] != '\0'; ++i){
		t = (int) s[i];
		for (; t != 0; ++j){
			a[j] = t % 2;
			t >>= 1;
		}
		for (;j % 8 != 0; ++j){
			a[j] = 0;
		}
		for (k = 0;k < 4; ++k){
			if (a[j-8+k] != a[j-k-1]){    //这个if为了提高效率
				//cout<<"a[j-8+k]="<<a[j-8+k]<<"a[j-k-1]="<<a[j-k-1]<<endl;
				t = a[j-8+k];
				a[j-8+k] = a[j-k-1];
				a[j-k-1] = t;
			}
		}
		//cout<<endl;
	}
}

//二进制转字符串
string binaryToString(int b[], int length){
	int i = 0, sum = 0;
	string s;
	while(true){
		if (i%8 == 0){
			s = s + (char)sum;
			sum = 0;
		}
		if (i > length) break;
		sum *= 2;
		sum += b[i];
		++i;
	}
	return s;
}

//表置换操作(row_size:表一行的个数,line_size:表一列的个数)
void table_replace(int origin[], int *p, int row_size, int line_size){
	int tmp[64], i;
	int length = row_size * line_size;
	for(i = 0; i < length; ++i){
		tmp[i] = origin[*(p+(i/row_size)*row_size+(i%row_size))-1];  //减1!!!
		//cout<<"tmp="<<tmp[i]<<" i="<<i<<" n="<<i%row_size<<" m="<<(i/row_size)*row_size<<" table="<<*(p+(i/row_size)*row_size+(i%row_size))-1<<endl;
	}
	for(i = 0; i < length; ++i){
		origin[i] = tmp[i];
	}
}

//S-Boxes操作
void S_box_func(int a[]){
	int i, j, k, t=0, m, n, count;
	int s[8];
	for (i = 0, k = 0; i < 48; i += 6){
		m = a[i]*2 + a[i+5];
		n = a[i+1]*8 + a[i+2]*4 + a[i+3]*2 + a[i+4];
		//cout<<"m = "<<m<<" n = "<<n<<" a[i] = "<<a[i]<<" a[i+5] = "<<a[i+5]<<endl;
		s[i/6] = S_Boxes[i/6][m][n];
	}
	/*for (i = 0; i < 8; ++i){
		cout<<s[i]<<' ';
	}
	cout<<endl<<endl;*/
	for (i = 0; i < 8; ++i, t += 4){
		j = 3;
		for (count = 0; s[i] != 0; --j, ++count){
			a[t+j] = s[i] % 2;
			s[i] >>= 1;
		}
		for (;count < 4; --j, ++count){
			a[t+j] = 0;
		}
	}
}

//异或操作
void XOR(int a[], int b[], int size){
	//int size = sizeof(a)/sizeof(int);
	int i;
	for(i = 0; i < size; ++i){
		//cout<<b[i]<<endl;
		a[i] ^= b[i];
	}
}

////密钥循环左移
//int rotateLeft(int a[]){
//	int i, j, tmp;
//	for (i = 0; i < 16;  ++i){
//		rol(a, (int *)Shift_table, i);
//	}
//}

//循环左移函数
void rol(int a[], int *p, int num){
	int i, j, n = *(p+num);
	int tmp;
	for (j = 0; j < n; ++j){
		tmp = a[0];
		for (i = 0; i < 27; ++i){
			a[i] = a[i+1];
		}
		a[27] = tmp;
	}
}

//字符串分半
void cutString(int ip[], int L[], int R[], int size){
	//cout<<"SIZE="<<size<<endl;
	for (int i = 0; i < size/2; ++i){
		L[i] = ip[i];
		R[size/2-i-1] = ip[size-i-1];
	}
}

//算出所有的子密钥保存到全局变量e_key[16][48]中
void solutionKey(string key){
	int ik[64], k[56], C[28], D[28];
	int i, j;

	stringToBinary(key, ik);
	//cout<<"key binary:"<<endl;
	//printv(ik, 64);
	table_replace(ik, (int *)PC1_table, 7, 8);
	cutString(ik, C, D, 56);
	for(i = 0; i < 16; ++i){
		rol(C, (int *)Shift_table, i);
		rol(D, (int *)Shift_table, i);
		for(j = 0; j < 28; ++j){
			k[j] = C[j];
			k[28+j] = D[j];
		}
		table_replace(k, (int *)PC2_table, 6, 8);
		for(j = 0; j < 48; ++j){
			e_key[i][j] = k[j];
		}
	}
}

//加密
string encrypt(string plain, string key, int mode, int a[]){
	int ip[64], L[32], R[32], ER[48];
	int i, j;

	solutionKey(key);
	stringToBinary(plain, ip);
	table_replace(ip, (int *)IP_table, 8, 8);
	//cout<<"plain after IP_table:"<<endl;
	//printv(ip, 64);
	cutString(ip, L, R, 64);
	for (i = 0; i < 16; ++i){
		for (j = 0; j < 32; ++j){
			ER[j] = R[j];
		}
		table_replace(ER, (int *)E_table, 6, 8);
		if (mode == 1)
			XOR(ER, e_key[i], 48);
		else
			XOR(ER, e_key[15-i], 48);
		S_box_func(ER);
		//cout<<"ER after s-box binary:"<<endl;
		//printv(ER, 48);
		table_replace(ER, (int *)P_table, 4, 8);
		for (j = 0; j < 32; ++j){
			ER[j] ^= L[j];
			L[j] = R[j];
			R[j] = ER[j];
		}
	}
	for (i = 0; i < 32; ++i){
		ip[i] = R[i];
		ip[i+32] = L[i];
	}
	table_replace(ip, (int *)IPR_table, 8, 8);
	for(i = 0; i < 64; ++i){
		a[i] = ip[i];
	}
	return binaryToString(ip, 64);
}

//解密
string decrypt(string cipher, string key, int a[]){
	return NULL;
}

//test
void printv(int a[], int size){
	for(int i = 0; i < size; ++i){
		if (i%8 == 0 && i > 1)
			cout<<"  ";
		cout<<a[i];
	}
	cout<<endl<<endl;
}