⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 des_cipher.cpp

📁 这是我编的包括古典密码
💻 CPP
字号:
// DES_Cipher.cpp : implementation file
//

#include "stdafx.h"
#include "MY_CAP.h"
#include "math.h"
#include "DES_Cipher.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDES_Cipher dialog

CMY_CAPDlg *Main_CapD;
CDES_Cipher::CDES_Cipher(CWnd* pParent /*=NULL*/)
	: CDialog(CDES_Cipher::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDES_Cipher)
	m_strKeyWord = _T("");
	m_strHint = _T("");
	Init_IP();
	Init_PC();
	Init_SBox();
	Innit_PBox();
	//}}AFX_DATA_INIT
}


void CDES_Cipher::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDES_Cipher)
	DDX_Text(pDX, IDC_KEYWORD, m_strKeyWord);
	DDV_MaxChars(pDX, m_strKeyWord, 8);
	DDX_Text(pDX, IDC_HINT, m_strHint);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDES_Cipher, CDialog)
	//{{AFX_MSG_MAP(CDES_Cipher)
	ON_COMMAND(IDD_ENCIPHER, OnEncipher)
	ON_COMMAND(IDD_DECIPHER, OnDecipher)
	ON_COMMAND(IDD_HELP, OnHelp)
	ON_COMMAND(IDD_QUIT, OnQuit)
	ON_COMMAND(IDD_EVALUATE, OnEvaluate)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDES_Cipher message handlers

void CDES_Cipher::Trans_Dialog(CWnd *temp)
{
	Main_CapD = (CMY_CAPDlg *)temp;
}

void CDES_Cipher::ProduceIntArray(int *IntKeyWord, CString Plaintext)
{
	int temp;
	for (int i = 0; i < 64; i++)
	{
		if (i % 8 == 0) 
		{
			temp = Plaintext[i / 8];
		}
		IntKeyWord [i] = temp / (int)pow(2, 7 - (i % 8)); 
		temp = temp % (int)pow(2, 7 - (i % 8));
	}
}

void CDES_Cipher::DistillCAndD(int *KeyWord, int length)
{
	int temp[64];
	int i, j = 0;
	for (i = 0; i < length; i++)
	{
		temp [i] = KeyWord [i];
	}
	for (i = 0; i < 64; i++) //包括(pc-1)置换选择
	{
		if ((i + 1) % 8 != 0)
		{
			if (j < 28)
			{
				m_C [j] = temp [PC1[j] - 1];
			}
			else
			{
				m_D [j % 28] = temp [PC1[j] - 1];
			}
			j++;
		}
	}
}

int * CDES_Cipher::CycLeft(int *Array, int length, int digit)
{
	int i, *temp = new int [length];
	for (i = 0; i < length; i++)
	{
		temp [i] = Array [i];
	}
	for (i = 0; i < length; i++)
	{
		Array [i] = temp [(i + digit) % length];
	}
	delete []temp;
	return Array;
}

int * CDES_Cipher::PC2Rplacement(int *C, int *D) //选择置换(PC-2)
{
	int i;
	int temp [56];
	for (i = 0; i < 56; i++)
	{
		if (i < 28) temp [i] = C[i];
		else temp [i] = D[i % 28];
	}
	for (i = 0; i < 48; i++)
	{
		Key [i] = temp [PC2[i] - 1];
	}
	return Key;
}

int * CDES_Cipher::ProduceAKey(int *C, int *D, int digit) //生成一个密钥
{
	if (digit == 1 || digit == 2 || digit == 9 || digit == 16)
	{
		CycLeft(C, 28, 1);
		CycLeft(D, 28, 1);
	}
	else 
	{
		CycLeft(C, 28, 2);
		CycLeft(D, 28, 2);
	}
	return PC2Rplacement(C, D);
}

BOOL CDES_Cipher::ProduceKey() // 生成密钥
{
	int i;
	if (m_strKeyWord.GetLength () != 8) return FALSE;
	ProduceIntArray(m_IntKeyWord, m_strKeyWord);
	DistillCAndD(m_IntKeyWord, 64);
	for (i = 0; i < 16; i++)
	{
		ProduceAKey (m_C, m_D, i + 1);
		EvaluateArray(m_Key[i], Key, 48);
	}
	return TRUE;

}

CString CDES_Cipher::ProduceCipher(CString Ciphertext, int *m_plain)
{
	int i = 1;
	Ciphertext = "";
	Init_PlaceIP(m_plain);
	for (i = 0; i < 16; i++)
	{
		FFunction (R, m_Key[i]); // f(R(i-1),K(i))
		XOROperation (m_PBoxOut, L, 32);  // L(i-1) ^ f(R(i-1),K(i))
		EvaluateArray(L, R, 32); // L(i) = R (i -1)
		EvaluateArray(R, m_PBoxOut, 32); // R(i) = L(i-1) ^ f(R(i-1),K(i))
	}
	IPAPlace(m_CipherArray, R, L);
	for (i = 0; i < 64; i++)
	{
		Ciphertext += m_CipherArray[i] + '0';
	}
	return Ciphertext;
}

CString CDES_Cipher::ProducePlain(CString Plaintext, int *CipherArray)
{
	int i = 1;
	Plaintext = "";
	Init_PlaceIP(CipherArray); // RL
	for (i = 0; i < 16; i++)
	{
		FFunction (R, m_Key[15 - i]); // f(L(i-1),K(i))
		XOROperation (m_PBoxOut, L, 32);  // R(i-1) ^ f(L(i-1),K(i))
		EvaluateArray(L, R, 32); // R(i) = L (i -1)
		EvaluateArray(R, m_PBoxOut, 32); //L(i) = R(i-1) ^ f(L(i-1),K(i))
	}
	int temp;
	IPAPlace(m_Plain, R, L);
	for (i = 0; i < 64;)
	{
		temp = 0;
		while (true)
		{
			temp += m_Plain[i] * (int)pow(2, 7 - (i % 8));
			i++;
			if (i % 8 == 0) break;
		}
		Plaintext += temp;
	}
	return Plaintext;
}

CString CDES_Cipher::ManagePlaintext(CString Plaintext, int digit)
{
	int length = Plaintext.GetLength ();
	int i;
	CString temp = "";
	for (i = digit * 8; i < length; i++)
	{
		temp += Plaintext [i];
		if (temp.GetLength () == 8) break;
	}
	if (temp.GetLength () == 0) return temp;
	else if (temp.GetLength () != 8)
	{
		while (true)
		{
			temp += ' ';
			if (temp.GetLength () >= 8) break;
		}
	}
	return temp;
}

BOOL CDES_Cipher::ManageCiphertext(CString Ciphertext)
{
	int i, j = 0;
	int length = Ciphertext.GetLength ();
	if (sign >= length) return FALSE;
	for (i = sign; i < length; i++)
	{
		if (Ciphertext [i] == '0' || Ciphertext [i] == '1')
		{
			m_CipherArray [j++] = Ciphertext [i] - '0';
		}
        if (j == 64) break;
	}
	if (j != 64) return FALSE;
	sign = i + 1;
	return TRUE;
}

void CDES_Cipher::OnEncipher() 
{
	// TODO: Add your command handler code here
	UpdateData (TRUE);
	if (ProduceKey() == FALSE)
	{
		m_strHint = "The key is wrong size!";
		UpdateData(FALSE);
		MessageBeep(MB_ICONEXCLAMATION);
		return;
	}
	m_strHint = "";
	UpdateData(FALSE);
	Main_CapD -> UpdateData (TRUE);
	m_Plaintext = Main_CapD -> m_Plaintext;
	Main_CapD -> m_Ciphertext = "";
	CString Plaintext = "";
	int i = 0;
	while (true)
	{
		Plaintext = ManagePlaintext(m_Plaintext,i);
		i++;
		if (Plaintext == "") break;
		ProduceIntArray (m_Plain,Plaintext);
		Main_CapD -> m_Ciphertext += ProduceCipher(m_Plaintext, m_Plain);
	}
	Main_CapD -> UpdateData (FALSE);
	if (Main_CapD ->m_Ciphertext.GetLength () != 0)
		Main_CapD -> OnSave_Ciphertext ();
}

void CDES_Cipher::OnDecipher() 
{
	// TODO: Add your command handler code here
	UpdateData (TRUE);
	if (ProduceKey() == FALSE)
	{
		m_strHint = "The key is wrong size!";
		UpdateData(FALSE);
		MessageBeep(MB_ICONEXCLAMATION);
		return;
	}
	m_strHint = "";
	UpdateData(FALSE);
	sign = 0;
	Main_CapD -> UpdateData (TRUE);
	m_Ciphertext = Main_CapD -> m_Ciphertext;
	Main_CapD -> m_Plaintext = "";
	CString Ciphertext;
	int i = 0;
	while (true)
	{
		if (ManageCiphertext (m_Ciphertext) == FALSE) break;
		Main_CapD -> m_Plaintext += ProducePlain(Ciphertext, m_CipherArray);
	}
	Main_CapD -> UpdateData (FALSE);
	if (Main_CapD->m_Plaintext.GetLength () != 0)
		Main_CapD -> OnSave_Plaintext ();
}

void CDES_Cipher::OnEvaluate() 
{
	// TODO: Add your command handler code here
}

void CDES_Cipher::Init_PlaceIP(int *m_plain) //初始置换IP
{
	for (int i = 0; i < 64; i++)
	{
		if (i < 32)
		{
			L [i] = m_plain [IP[i] - 1];
		}
		else
		{
			R [i % 32] = m_plain [IP[i] - 1];
		}
	}
}

int * CDES_Cipher::IPAPlace(int *CipherArray, int *RL, int *LL)//逆初始转换IP逆
{
	int temp[64];
	for (int i = 0; i < 64; i++)
	{
		if (i < 32) 
			temp [i] = RL [i];
		else temp[i] = LL [i % 32];
	}
	for (i = 0; i < 64; i++)
	{
		CipherArray [i] = temp [ IPA[i] - 1];
	}
	return CipherArray;
}

int * CDES_Cipher::FFunction(int *Ri, int *KeyArray)
{
	ExpandManagement(Ri);
	XOROperation(m_ExpandPlain,KeyArray,48);
	SBoxSelection(m_SBoxOut,m_ExpandPlain,48);
	PBoxArange(m_SBoxOut,32);
	return m_PBoxOut;
}

int * CDES_Cipher::ExpandManagement(int *Ri) // 扩展置换 (Ri是32位)
{
	int i = 0, j = 0;
	while (true)
	{
		if (j % 6 == 0)
		{
			m_ExpandPlain [j] = Ri [(i + 31) % 32];
			j++;
		}
		else  if (j % 6 == 5)
		{
			m_ExpandPlain [j] = Ri [i % 32];
			j++;
		}
		else
		{
			m_ExpandPlain [j] = Ri [i];
			i++;
			j++;
		}
		if (j >= 48 ) break;
	}
	return m_ExpandPlain;
}

int * CDES_Cipher::XOROperation(int *ArrayL, int *ArrayR, int length) //48位
//异或运算
{
	for (int i = 0; i < length; i++)
	{
		ArrayL [i] = ArrayL [i] ^ ArrayR [i];
	}
	return ArrayL;
}

int * CDES_Cipher::SBoxSelection(int *SBoxOut, int *ExpandPlain, int length)
//S盒选择
{
	int i = 0, j = 0, k = 0;
	int Box = 0;
	int temp[2];
	int Result;
	for (i = 0; i < length;)
	{
		temp[0] = temp [1] = 0;
		for (j = 0; j < 6; j++)
		{
			if (j == 0) 
				temp[0] += ExpandPlain [i] * 2;
			else if (j == 5)
				temp[0] += ExpandPlain [i];
			else 
				temp [1] += ExpandPlain [i] * (int)pow (2, 4 - j );
			i++;
		}
		Result = SBox[Box][temp[0]][temp[1]];
		Box++;
		for (j = 3; j >= 0; j--)
		{
			SBoxOut [k++] = Result / (int)pow (2, j);
			Result = Result / (int)pow (2, j);
		}
	}
	return SBoxOut; //32位
}

int * CDES_Cipher::PBoxArange(int *SBoxOut, int length) //P盒排列
{
	for (int i = 0; i < length; i++)
	{
		m_PBoxOut [i] = SBoxOut [PBox[i] - 1];
	}
	return m_PBoxOut; //32bit
}

void CDES_Cipher::EvaluateArray(int *ArrayL, int *ArrayR, int length) //数组赋值
{
	for (int i = 0; i < length; i++)
		ArrayL [i] = ArrayR [i];
}

void CDES_Cipher::OnHelp() 
{
	// TODO: Add your command handler code here
	WinExec ("notepad.exe Help.txt", SW_SHOW);
}

void CDES_Cipher::OnQuit() 
{
	// TODO: Add your command handler code here
	OnCancel ();
}

void CDES_Cipher::Init_PC()
{
	int temp[56] =
	{
		57,49,41,33,25,17,9,
		1,58,50,42,34,26,18,
		10,2,59,51,43,33,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
	};
	for (int i = 0; i < 56; i++)
		PC1 [i] = temp [i];
	int Temp [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
	};
	for (i = 0; i < 48; i++)
		PC2 [i] = Temp [i];
}

void CDES_Cipher::Init_IP()
{
	int temp [64] =
	{
	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
	};
	for (int i = 0; i < 64; i++)
		IP[i] = temp[i];
	int Temp[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
	};
	for (i = 0; i < 64; i++)
		IPA [i] = Temp [i];
}

void CDES_Cipher::Init_SBox()
{
	int temp[8][4][16] = 
	{
		{
			{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 i, j = 0, z = 0;
	for (i = 0; i < 8; i++)
	{
		for (j = 0; j < 4; j++)
		{
			for (z = 0; z < 16; z++)
				SBox[i][j][z] = temp[i][j][z];
		}
	}
}
void CDES_Cipher::Innit_PBox()
{
	int temp[32] = 
	{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};
	for (int i = 0; i < 32; i++)
	{
		PBox [i] = temp [i];
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -