信息安全实验--DES算法

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

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

发上来留个纪念。吐舌头

 

#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;
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值