使用C语言实现多线程DES算法、CPC密码和vigenere算法

UI.h
#include "Vigenere.h"
#include "CPC.h"
#include "DES.h"

void Surface();
void VegeSurface();
void CPCSurface();
void DESSurface();
UI.cpp
#include <iostream>
#include <conio.h>
#include "UI.h"

using namespace std;

void main()
{
	Surface();
}

void Surface()
{
	system("cls");
	cout << "1.Vigenere Cipher"<< endl;
	cout << "2.Column Permutation Cipher" << endl;
	cout << "3.DES" << endl;
	cout << "4.Exit" << endl << endl << endl;
	char choice;
	choice = getch();
	switch (choice)
	{
	case '1':VegeSurface(); break;
	case '2':CPCSurface(); break;
	case '3':DESSurface(); break;
	default:break;
	}
}

void VegeSurface()
{
	system("cls");
	cout << "1.Encryption" << endl;
	cout << "2.Decryption" << endl;
	cout << "3.back" << endl;
	char choice;
	choice = getch();
	switch (choice)
	{
	case '1':VigenereEn(); break;
	case '2':VigenereDe(); break;
	case '3':Surface(); break;
	default:break;
	}
	Surface();
}

void CPCSurface()
{
	system("cls");
	cout << "1.Encryption" << endl;
	cout << "2.Decryption" << endl;
	cout << "3.back" << endl;
	char choice;
	choice = getch();
	switch (choice)
	{
	case '1':CPCEn(); break;
	case '2':CPCDe(); break;
	case '3':Surface(); break;
	default:break;
	}
	Surface();
}

void DESSurface()
{
	system("cls");
	cout << "1.Encryption" << endl;
	cout << "2.Decryption" << endl;
	cout << "3.back" << endl;
	char choice;
	choice = getch();
	switch (choice)
	{
	case '1':DES(choice); break;
	case '2':DES(choice); break;
	case '3':Surface(); break;
	default:break;
	}
	Surface();
}
DES.h
int DES(char choice);

int getText(char choice);

//char and bit
void OutputChar(char a);
void SetCharBit(char *p, int pos, int bit);
int getCharPos(char a, int pos);
void Output(char a[]);

//key
void Add8Bit();
void PC_1();
void GeneratingSubkey();
void OutputSubkey();

//encryption and decryption
int AddText(int n);
void IT(char *text, char *LP, char *RP, int e);
void EBOX(char *EOut, char *RP);
void SBOX(int stage, char *SIn, char *EOut, char *SOut);
void PBOX(char *SOut, char *POut);
void CHANGE(char *LP, char *RP, char *POut);
void FT(char *LP, char *RP, int e);
void Write2File(int n);
int DeleteQ(int len);
 DES.cpp
#include "DES.h"
#include "Order.h"
#include "Common.h"
#include <windows.h>
#include <fstream>
#include <iostream>

using namespace std;

//-----------------------------------------------------------------------------------------
//text
char TotalText[9999];
char AimText[9999];

//key
char subkey[16][7];
char MasterKey[9];
char key1[8];
char key2[8];
char key[2][8];

int EN_OR_DE = 0;                //a flag
//-----------------------------------------------------------------------------------------

HANDLE hKEY, hENORDE[999], hWAIT;             //定义线程句柄

DWORD WINAPI KEY(LPVOID lpParameter);
DWORD WINAPI ENORDE(LPVOID lpParameter);
DWORD WINAPI WAIT(LPVOID lpParameter);

//-----------------------------------------------------------------------------------------

int DES(char choice)
{
	TotalText[0] = '\0';
	AimText[0] = '\0';
	int i = getText(choice);
	if (0 == i)
		return 0;

	hKEY = ::CreateThread(NULL, 0, KEY, NULL, 0, NULL);						  //创建key线程

	int block = AddText(i) / 8 - 1;
	int e[999];
	
	AimText[(block + 1) * 8] = '\0';
	
	hWAIT = ::CreateThread(NULL, 0, WAIT, &block, 0, NULL);						 
	for (i = 0; i <= block; i++)
	{
		e[i] = i;
		hENORDE[i] = ::CreateThread(NULL, 0, ENORDE, &e[i], 0, NULL);
	}
	while (1)
	{
		if (WaitForSingleObject(hWAIT, INFINITE) == WAIT_OBJECT_0)          //等待加密/解密过程结束
			break;
	}

	for (i = 0; i <= block; i++)
		::CloseHandle(hENORDE[i]);
	::CloseHandle(hKEY);
	::CloseHandle(hWAIT);
	
	Write2File((block + 1) * 8);
	return 1;
}

//-----------------------------------------------------------------------------------------
//function about char and output

//output a char as 0s and 1s
void OutputChar(char a)
{
	cout << endl;
	int j = 0;
	for (j = 0; j <= 7; j++)
	{
		cout << ((a >> (7 - j)) & 1);
	}
	cout << endl;
}

void SetCharBit(char *p, int pos, int bit)
{
	*p = ((*p) | (~x[pos])) & ((bit << (7 - pos) | x[pos]));
}

int getCharPos(char a, int pos)         //a is char, pos //
{
	return ((a >> (7 - pos)) & 1);
}

//output a char[] as 0s and 1s
void Output(char a[])
{
	int k = 1, i = 0, j = 0;
	for (i = 0; i < strlen(a); i++)
	{
		for (j = 0; j <= 7; j++)
		{
			cout << ((a[i] >> (7 - j)) & 1);
			if (0 == k % 8)
				cout << endl;
			k++;
		}
	}
	cout << endl << endl;
}

//----------------------------------------------------------------------------------------
//deal with key

//key线程
DWORD WINAPI KEY(LPVOID lpParameter)
{
	Add8Bit();
	PC_1();
	GeneratingSubkey();
	//OutputSubkey();
	return 0;
}

void Add8Bit()
{
	//get key from keyboard
	cout << "enter key      ";
	cin >> key1;
	system("cls");

	//第a位(按数组,从0开始),第b个字符(按数组,从0开始)
	//flag用作奇偶校验(1的个数)
	//process of 56->64
	int i = 0, j = 0, flag = 0, a = 0, b = 0;
	char *p;
	for (i = 0; i <= 7; i++)
	{
		flag = 0;
		p = &MasterKey[i];
		for (j = 0; j <= 6; j++)
		{
			SetCharBit(p, j, getCharPos(key1[b], a));
			if (0 == getCharPos(key1[b], a))
				flag++;
			a++;
			if (8 == a)
			{
				a = 0;
				b++;
			}
		}
		SetCharBit(p, j, flag % 2);
	}
	/*
	cout << "the 56-bit key that you enter" << endl;
	Output(key1);
	cout << "the 64-bit key after adding 8 additional 0s and 1s" << endl;
	Output(MasterKey);
	*/
}

void PC_1()
{
	int i = 0, j = 0, a = 0, b = 0, k = 0;
	char *p;
	for (i = 0; i <= 6; i++)
	{
		p = &key2[i];
		for (j = 0; j <= 7; j++)
		{
			a = Pc1Order[k] % 8;  //a!=0
			b = (Pc1Order[k] - a) / 8;
			a--;
			SetCharBit(p, j, getCharPos(MasterKey[b], a));
			k++;
		}
	}
	/*
	cout << "the 56-bit key after the 64-bit key discarding 8,16,24,32,40,48,56,64" << endl;
	Output(key2);
	*/
}

void GeneratingSubkey()
{
	//process of generating subkey
	int i = 0, j = 0, shiftBit = 0, k = 0;
	int a = 0, b = 0, c = 0, d = 0, u = 0;
	char *p;
	for (i = 0; i <= 15; i++)
		subkey[i][6] = '\0';
	for (i = 0; i <= 6; i++)
		key[0][i] = key2[i];
	for (i = 0; i <= 15; i++)
	{

		//cyclic left shift
		if (0 == i || 1 == i || 8 == i || 15 == i)
		{
			shiftBit = 1;

			//left part
			p = &key[(i + 1) % 2][3];
			SetCharBit(p, 3, getCharPos(key[i % 2][0], 0));

			//right part
			p = &key[(i + 1) % 2][6];
			SetCharBit(p, 7, getCharPos(key[i % 2][3], 4));
		}
		else
		{
			shiftBit = 2;

			//left part
			p = &key[(i + 1) % 2][3];
			SetCharBit(p, 2, getCharPos(key[i % 2][0], 0));
			p = &key[(i + 1) % 2][3];
			SetCharBit(p, 3, getCharPos(key[i % 2][0], 1));

			//right part
			p = &key[(i + 1) % 2][6];
			SetCharBit(p, 7, getCharPos(key[i % 2][3], 5));
			p = &key[(i + 1) % 2][6];
			SetCharBit(p, 6, getCharPos(key[i % 2][3], 4));
		}
		for (j = 0; j <= 55 - shiftBit; j++)
		{
			a = j % 8;
			b = (j - a) / 8;
			c = a + shiftBit;
			d = b;
			if (8 == c || 9 == c)
			{
				c = c - 8;
				d++;
			}
			SetCharBit(&key[(i + 1) % 2][b], a, getCharPos(key[i % 2][d], c));
			if (27 - shiftBit == j)
				j = 27;
		}

		//PC_2
		k = 0;
		for (u = 0; u <= 5; u++)
		{
			p = &subkey[i][u];
			for (j = 0; j <= 7; j++)
			{
				a = (Pc2Order[k] - 1) % 8;
				b = (Pc2Order[k] - 1 - a) / 8;
				SetCharBit(p, j, getCharPos(key[(i + 1) % 2][b], a));
				k++;
			}
		}
		/*
		cout << "before PC-2 of " << i << " stage" << endl;
		Output(key[(i + 1) % 2]);
		cout << endl << "subkey" << "[" << i << "]" << endl;
		Output(subkey[i]);
		cout << endl;
		*/
	}
}

void OutputSubkey()
{
	int i = 0, j = 0, k = 0, m = 0;
	for (m = 0; m <= 3; m++)
	{
		for (i = m * 4; i <= m * 4 + 3; i++)
		{
			cout << "          subkey" << "[" << i << "]";
			if (i < 10)
				cout << "     ";
			else
				cout << "    ";
		}
		cout << endl << endl;
		for (i = 0; i <= 5; i++)
		{
			for (j = m * 4; j <= m * 4 + 3; j++)
			{
				cout << "          ";
				for (k = 0; k <= 7; k++)
				{
					cout << ((subkey[j][i] >> (7 - k)) & 1);
				}
				cout << "      ";
			}
			cout << endl;
		}
		cout << endl << endl;
	}
	cout << endl << endl;
}

//----------------------------------------------------------------------------------------
//encipher or decipher

DWORD WINAPI ENORDE(LPVOID lpParameter)
{
	int e = *(int*)lpParameter;
	int stage = 0;
	char text[9], LP[4], RP[4], EOut[7], SIn[7], SOut[5], POut[5];
	while (1)
	{
		if (WaitForSingleObject(hKEY, INFINITE) == WAIT_OBJECT_0)                                //等待KEY线程生成密钥结束
		{
			IT(text, LP, RP, e);
			for (stage = 0; stage <= 15; stage++)
			{
				EBOX(EOut, RP);
				SBOX(stage, SIn, EOut, SOut);
				PBOX(SOut, POut);
				CHANGE(LP, RP, POut);
			}
			FT(LP, RP, e);
			break;
		}
	}
	return 1;
}

//get plaintext or ciphertext
int getText(char choice)
{
	int i;
	char source = TextSource();
	EN_OR_DE = 0;
	if ('2' == source)
	{
		if ('1' == choice)
			cout << "enter plaintext   ";
		else
		{
			cout << "enter ciphertext   ";
			EN_OR_DE = 1;
		}
		cin >> TotalText;
		return strlen(TotalText);
	}
	else if ('1' == source)
	{
		ifstream fin;
		if ('1' == choice)
			fin.open("e:\\plaintext.txt", ios::binary);
		else
		{
			fin.open("e:\\ciphertext.txt", ios::binary);
			EN_OR_DE = 1;
		}
		if (!fin)
		{
			cout << "can't find the file...." << endl;
			system("pause");
			return 0;
		}
		else
		{
			char ch;
			for (i = 0; i < 9999; i++)
			{
				fin.get(ch);
				if (fin.eof())
				{
					TotalText[i] = '\0';
					break;
				}
				else
				{
					TotalText[i] = ch;
				}
			}
		}
		fin.close();
	}
	return i;
}

//add q at the last of the text
int AddText(int n)
{
	int len = n;
	int a = len % 8;
	int i = 0;
	if (a != 0)
	{
		for (i = len; i < len + (8 - a); i++)
			TotalText[i] = 'q';
		TotalText[i] = '\0';
		len = len + 8 - a;
	}
	return len;
}

void IT(char *text, char *LP, char *RP, int e)
{
	int i = 0, j = 0;
	int a = 0, b = 0;
	char PreText[9];
	PreText[8] = '\0';
	for (i = 0; i <= 7; i++)
		PreText[i] = TotalText[e * 8 + i];

	//IT
	for (i = 0; i <= 7; i++)
	{
		for (j = 0; j <= 7; j++)
		{
			a = ITOrder[i * 8 + j] % 8;
			b = (ITOrder[i * 8 + j] - a) / 8;
			if (0 == a)
				a = 8;
			else
				b++;
			//get a & b
			text[i] = (text[i] | (~x[j]))&(((((PreText[b - 1] >> (8 - a)) & 1) << (7 - j)) | x[j]));
		}
	}
	text[8] = '\0';

	//divide text into right part and left part
	for (i = 0; i <= 7; i++)
	{
		if (i <= 3)
			LP[i] = text[i];
		else
			RP[i - 4] = text[i];
	}
	//LP[4] = '\0';
	//RP[4] = '\0';
}

void EBOX(char *EOut, char *RP)
{
	int i = 0, j = 0, a = 0, b = 0;
	for (i = 0; i <= 5; i++)
	{
		for (j = 0; j <= 7; j++)
		{
			a = EOrder[i * 8 + j] % 8;
			b = (EOrder[i * 8 + j] - a) / 8;
			if (0 == a)
				a = 8;
			else
				b++;
			//get a & b
			EOut[i] = (EOut[i] | (~x[j]))&((((RP[b - 1] >> (8 - a)) & 1) << (7 - j)) | x[j]);
		}
	}
}

void SBOX(int stage, char *SIn, char *EOut, char *SOut)
{
	//decide encipher or decipher
	if (1 == EN_OR_DE)
		stage = 15 - stage;
	int i = 0, j = 0;

	//xor
	for (i = 0; i <= 5; i++)
		SIn[i] = EOut[i] ^ subkey[stage][i];

	//SBox
	int xpos = 0, ypos = 0, pos = 0;
	int a = 0, b = 0;
	for (i = 0; i <= 7; i++)
	{
		ypos = 0;
		//找到每一块的初始位
		a = (i * 6) % 8;      //第a位(按数组,从0开始)
		b = (i * 6 - a) / 8;  //第b个字符(按数组,从0开始)
		xpos = getCharPos(SIn[b], a) * 2;
		for (j = 1; j <= 4; j++)
		{
			a++;
			if (8 == a)
			{
				a = 0;
				b++;
			}
			ypos += getCharPos(SIn[b], a)*pow(2, 4 - j);
		}
		a++;
		if (8 == a)
		{
			a = 0;
			b++;
		}
		xpos += getCharPos(SIn[b], a);
		//by now,we get xpos and ypos
		//we use 0x0F and 0xF0
		if (i != 0 && 0 == i % 2)
			pos++;
		SOut[pos] = (SOut[pos] & z[i % 2]) | (y[SBox[i][xpos * 16 + ypos]] << (((i + 1) % 2) * 4));
	}
}

void PBOX(char *SOut, char *POut)
{
	int i = 0, j = 0;
	int a = 0, b = 0;
	for (i = 0; i <= 3; i++)
	{
		for (j = 0; j <= 7; j++)
		{
			a = POrder[i * 8 + j] % 8;
			b = (POrder[i * 8 + j] - a) / 8;
			if (0 == a)
				a = 8;
			else
				b++;
			//get a & b
			POut[i] = (POut[i] | (~x[j]))&((((SOut[b - 1] >> (8 - a)) & 1) << (7 - j)) | x[j]);
		}
	}
}

void CHANGE(char *LP, char *RP, char *POut)
{
	char w[5];
	int i = 0;
	for (i = 0; i <= 3; i++)
		w[i] = RP[i];
	for (i = 0; i <= 3; i++)
		RP[i] = POut[i] ^ LP[i];
	for (i = 0; i <= 3; i++)
		LP[i] = w[i];
}

void FT(char *LP, char *RP, int e)
{
	char AfterText[9];
	char SubAimText[9];
	int i = 0, j = 0;
	int a = 0, b = 0;
	for (i = 0; i <= 3; i++)
		AfterText[i] = RP[i];
	for (i = 4; i <= 7; i++)
		AfterText[i] = LP[i - 4];

	//FT
	for (i = 0; i <= 7; i++)
	{
		for (j = 0; j <= 7; j++)
		{
			a = FTOrder[i * 8 + j] % 8;
			b = (FTOrder[i * 8 + j] - a) / 8;
			if (0 == a)
				a = 8;
			else
				b++;
			//get a & b
			SubAimText[i] = (SubAimText[i] | (~x[j]))&((((AfterText[b - 1] >> (8 - a)) & 1) << (7 - j)) | x[j]);
		}
	}

	//write SubAimText to AimText
	for (i = 0; i <= 7; i++)
		AimText[e * 8 + i] = SubAimText[i];
}

void Write2File(int n)
{
	ofstream fout;
	if (0 == EN_OR_DE)
	{
		remove("e:\\ciphertext.txt");
		fout.open("e:\\ciphertext.txt", ios::binary);
	}
	else
	{
		n = DeleteQ(n);
		remove("e:\\plaintext.txt");
		fout.open("e:\\plaintext.txt", ios::binary);
	}
	for (int i = 0; i < n; i++)
		fout << AimText[i];
	fout.close();
}

int DeleteQ(int len)
{
	int i = len - 1;
	while ('q' == AimText[i])
	{
		i--;
		cout << i;
	}
	i++;
	AimText[i] = '\0';
	return i;
}

//----------------------------------------------------------------------------------------
//wait 
DWORD WINAPI WAIT(LPVOID lpParameter)
{
	int block = *(int*)lpParameter;
	int finished = 0;
	while (finished<=block)
	{
		if (WaitForSingleObject(hENORDE[finished], INFINITE) == WAIT_OBJECT_0)                                //   等待加密/解密过程结束
		{
			finished++;
		}
	}
	return 0;
}
//----------------------------------------------------------------------------------------


CPC.h
#include "Common.h"

int CPCEn();
int CPCDe();
CPC.cpp
#include <iostream>
#include <fstream>
#include "CPC.h"


using namespace std;

//Column Permutation Cipher Encryption
//key必须是小写英文字母
//plaintext大小写字母均可
//null letter 是 q
int CPCEn()
{
	char plaintext[99];
	char ciphertext[99];
	char key[99];
	
	char choice = TextSource();
	if (choice == '2')
	{
		cout << "enter plaintext   ";
		cin >> plaintext;
	}
	else if (choice == '1')
	{
		ifstream fin;
		fin.open("e:\\plaintext.txt");
		if (!fin)
		{
			cout << "can't find the file...." << endl;
			system("pause");
			return 0;
		}
		else
		{
			fin.getline(plaintext, 99);
		}
		fin.close();
	}
	
	cout << "      enter key   ";
	cin >> key;

	//对plaintext的长度进行调整
	int d = strlen(key);
	int temp = strlen(plaintext);
	int i;
	if (temp % d != 0) {
		for (i = 1; i <= d - (temp % d); i++)
		{
			plaintext[temp + i - 1] = 'q';
		}
		plaintext[temp + i] = '\0';
	}
	//cout << plaintext << endl;

	//从key中获得order
	int j, k;
	int order[99];
	k = 1;
	for (i = 'a'; i <= 'z'; i++)
	{
		for (j = 0; j < strlen(key); j++)
		{
			if (key[j] == i)
			{
				order[j] = k;
				k++;
			}
		}
	}
	order[d] = '\0';
	cout << "order   ";
	for (i = 0; i<d; i++)
		cout << order[i];
	cout << endl;

	//加密过程
	//不用计算机实现时,需要先把plaintext写进矩阵,再按照order提取出来,形成ciphertext
	//在用计算机实现时可以直接把plaintext转变为ciphertext
	k = 0;
	for (j = 0; j < d; j++)
	{
		for (i = 0; i < strlen(plaintext) / d; i++)
		{
			ciphertext[k] = plaintext[i*d + order[j]-1];
			k++;
		}
	}
	ciphertext[k] = '\0';
	cout << "ciphertext   " << ciphertext;

	ofstream fout;
	fout.open("e:\\ciphertext.txt");
	fout << ciphertext << endl;
	fout.close();
	system("pause");
	return 1;
}

//Column Permutation Cipher Decryption
//null letter 是 q
int CPCDe()
{
	char plaintext[99];
	char ciphertext[99];
	char key[99];
	
	char choice = TextSource();
	if (choice == '2')
	{
		cout << "enter ciphertext  ";
		cin >> ciphertext;
	}
	else if (choice == '1')
	{
		ifstream fin;
		fin.open("e:\\ciphertext.txt");
		if (!fin)
		{
			cout << "can't find the file...." << endl;
			system("pause");
			return 0;
		}
		else
		{
			fin.getline(ciphertext, 99);
		}
		fin.close();
	}

	cout << "      enter key   ";
	cin >> key;

	//从key中获得order
	int i,j, k;
	int d = strlen(key);
	int order[99];
	k = 1;
	for (i = 'a'; i <= 'z'; i++)
	{
		for (j = 0; j < strlen(key); j++)
		{
			if (key[j] == i)
			{
				order[j] = k;
				k++;
			}
		}
	}
	order[d] = '\0';
	cout << "order   ";
	for (i = 0; i<d; i++)
		cout << order[i];
	cout << endl;

	//process of decrypyion
	k = -1;
	for (i = 0; i < strlen(ciphertext); i++)
	{
		if (0 == i % (strlen(ciphertext) / d))
			k++;
		plaintext[d* (i % (strlen(ciphertext) / d)) + order[k] - 1] = ciphertext[i];
	}
	i--;
	while('q' == plaintext[i])
	{
		i--;
	}
	plaintext[i+1] = '\0';
	cout << "plaintext   " << plaintext<<endl;

	ofstream fout;
	fout.open("e:\\plaintext.txt");
	fout << plaintext << endl;
	fout.close();
	system("pause");
	return 1;
}
Vigenere.h
#include "Common.h"

int VigenereEn();
int VigenereDe();
Vigenere.cpp
#include <iostream>
#include <fstream>
#include "Vigenere.h"


using namespace std;

//Vigenere Encryption


//keyword必须是小写英文字母
//plaintext大小写字母均可
int VigenereEn()
{
	char plaintext[99];
	char ciphertext[99];
	char keyword[99];
	int i=0;
	int flag=0;
	
	char choice = TextSource();
	if (choice == '2')
	{
		cout << "enter plaintext   ";
		cin >> plaintext;
	}
	else if (choice == '1')
	{
		ifstream fin;
		fin.open("e:\\plaintext.txt");
		if (!fin)
		{
			cout << "can't find the file...." << endl;
			system("pause");
			return 0;
		}
		else
		{
			fin.getline(plaintext, 99);
		}
		fin.close();
	}
	cout<< " enter keyword   ";
	cin>>keyword;
	for(i=0;i<strlen(plaintext);i++)
	{
		if(plaintext[i]>='a'&&plaintext[i]<='z')
			flag=0;
		else if(plaintext[i]>='A'&&plaintext[i]<='Z')
		{
			flag=1;
			plaintext[i]=plaintext[i]+32;
		}
		ciphertext[i]=((plaintext[i]-96)+(keyword[i%strlen(keyword)]-96)-1)%26+96;
		if (96 == ciphertext[i])
			ciphertext[i] = 'z';
		if(1==flag)
			ciphertext[i]=ciphertext[i]-32;
	}
	ciphertext[i]='\0';	
	cout << "     ciphertext   "<< ciphertext<<endl;
	
	ofstream fout;
	fout.open("e:\\ciphertext.txt");
	fout << ciphertext << endl;
	fout.close();
	system("pause");
	return 1;
}



//Vigenere Decryption
//keyword必须是小写英文字母
//ciphertext大小写字母均可

int VigenereDe()
{
	char plaintext[99];
	char ciphertext[99];
	char keyword[99];
	
	char choice = TextSource();
	if (choice == '2')
	{
		cout << "enter ciphertext  ";
		cin >> ciphertext;
	}
	else if (choice == '1')
	{
		ifstream fin;
		fin.open("e:\\ciphertext.txt");
		if (!fin)
		{
			cout << "can't find the file...." << endl;
			system("pause");
			return 0;
		}
		else
		{
			fin.getline(ciphertext, 99);
		}
		fin.close();
	}
	
	cout<< " enter keyword   ";
	cin>>keyword;
	int i=0;
	int flag=0;
	for(i=0;i<strlen(ciphertext);i++)
	{
		if(ciphertext[i]>='a'&&ciphertext[i]<='z')
			flag=0;
		else if(ciphertext[i]>='A'&&ciphertext[i]<='Z')
		{
			flag=1;
			ciphertext[i]=ciphertext[i]+32;
		}
		
		if(ciphertext[i]<keyword[i%strlen(keyword)])
			plaintext[i]=26-(keyword[i%strlen(keyword)]-ciphertext[i])+'a';
		else
			plaintext[i] =ciphertext[i] - keyword[i%strlen(keyword)] + 'a';
		
		if(1==flag)
			plaintext[i]=plaintext[i]-32;
	}
	plaintext[i]='\0';
	cout << "     plaintext  "<< plaintext<<endl;

	ofstream fout;
	fout.open("e:\\plaintext.txt");
	fout << plaintext << endl;
	fout.close();
	system("pause");
	return 1;
}

Common.h
#pragma once
char TextSource();
Common.cpp
#include <iostream>
#include <conio.h>
#include "Common.h"

using namespace std;

char TextSource()
{
	char choice;
	do
	{
		system("cls");
		cout << "Please choose plaintext/ciphertext source:" << endl;;
		cout << "1.File" << endl;
		cout << "2.Keyboard" << endl << endl;
		choice = getch();
	} while (choice != '1' && choice != '2');
	system("cls");
	return choice;
}
Order.h
#pragma once

char x[8] = { 0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE };
char y[17] = { 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF };
char z[2] = { 0x0F,0xF0 };

int ITOrder[] = { 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 };

int Pc1Order[56] = { 
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 };

int  Pc2Order[48] =
{
	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
};

int EOrder[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 };

int SBox[8][64] =
{
	{ 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 },

	{ 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 },

	{ 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 },

	{ 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 },

	{ 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 },

	{ 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 },

	{ 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 },

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

int POrder[] = { 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 };

int FTOrder[64] = { 
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 };

  • 14
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用C语言实现多线程加密文件的过程可以分为以下几个步骤: 1. 打开文件 使用`fopen()`函数打开需要加密文件,返回一个文件指针。 2. 确定文件大小 使用`fseek()`函数将文件指针移动到文件末尾,使用`ftell()`函数获取文件大小。 3. 创建多个线程 根据需要加密文件大小和线程数,创建多个线程。使用`pthread_create()`函数创建线程,传递需要处理的数据和线程处理函数。 4. 线程处理函数 每个线程处理一定数量的数据,对数据进行加密操作。加密可以使用常见的加密算法,例如AES、DES等。加密完成后,将加密后的数据写入到输出文件中。 5. 合并数据 等待所有线程处理完成,将所有加密后的数据合并成一个文件。 6. 关闭文件 使用`fclose()`函数关闭文件。 下面是一个简单的多线程加密文件的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define THREAD_NUM 4 typedef struct { FILE *in_file; FILE *out_file; int start; int end; } thread_arg_t; void *encrypt_thread(void *arg) { thread_arg_t *targ = (thread_arg_t *)arg; int block_size = 1024; char buffer[block_size]; int bytes_read; fseek(targ->in_file, targ->start, SEEK_SET); fseek(targ->out_file, targ->start, SEEK_SET); while (ftell(targ->in_file) < targ->end) { bytes_read = fread(buffer, 1, block_size, targ->in_file); // TODO: 加密操作 fwrite(buffer, 1, bytes_read, targ->out_file); } return NULL; } int main(int argc, char *argv[]) { if (argc < 3) { printf("Usage: %s <input_file> <output_file>\n", argv[0]); return -1; } FILE *in_file = fopen(argv[1], "rb"); if (!in_file) { printf("Cannot open input file %s\n", argv[1]); return -1; } FILE *out_file = fopen(argv[2], "wb"); if (!out_file) { printf("Cannot open output file %s\n", argv[2]); fclose(in_file); return -1; } int file_size = 0; fseek(in_file, 0, SEEK_END); file_size = ftell(in_file); fseek(in_file, 0, SEEK_SET); int block_size = file_size / THREAD_NUM; pthread_t threads[THREAD_NUM]; thread_arg_t thread_args[THREAD_NUM]; for (int i = 0; i < THREAD_NUM; i++) { thread_args[i].in_file = in_file; thread_args[i].out_file = out_file; thread_args[i].start = i * block_size; thread_args[i].end = (i == THREAD_NUM - 1) ? file_size : (i + 1) * block_size; pthread_create(&threads[i], NULL, encrypt_thread, &thread_args[i]); } for (int i = 0; i < THREAD_NUM; i++) { pthread_join(threads[i], NULL); } fclose(in_file); fclose(out_file); return 0; } ``` 在这个示例代码中,我们创建了4个线程来并行加密文件。每个线程处理一定数量的数据,加密后写入到输出文件中。在加密操作中,我们使用了一个TODO标记,可以根据需要替换成实际的加密算法。注意,在多线程处理文件时,需要注意多线程之间的同步和加锁问题,避免出现数据竞争和不一致的情况。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值