📄 des_cipher.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 + -